0

Have objects in laravel:

use AAA;
use BBB;
use CCC;
...

From input getting the name: "AAA...";

$from_input = $some_input;

can I accomplish this:

$obj = new $from_input;
return $obj::where('status', 1)->get();

"new" function cannot find the class "AAA"

strval not helping. Please advice.

2 Answers 2

2

Security Notice Due to the insecurity of allowing an end user to instantiate any class through this method, I highly recommend against doing this and following my example at the bottom.

Class imports are not evaluated at runtime. You'd have to use the full path to the class to dynamically instantiate it as illustrated in this example:

<?php

namespace One {
    use Two\B;

    class A {
        function __construct($className) {
            echo "Attempting to construct $className..";
            new $className;
        }
    }

    new A(B::class); // Works since the B import is evaluated before runtime.
    try {
        new A("B"); // Doesn't work since "B" is not evaluated until runtime
    }
    catch (\Throwable $e) {
        echo $e->getMessage() . "\n";
    }
    new A("Two\B"); // Works since you use the full path to B.
}

namespace Two {
    class B {
        function __construct() {
            echo "B constructed!\n";
        }
    }

}

https://3v4l.org/LTdQN


While you could do this, that's asking for trouble. What would stop someone from retrieving data out of some model they shouldn't have access to?

Instead, build up an array of available classes and let them pass the array key instead of passing the name of the class.

$classes = [
   'a' => AAA::class,
   'b' => BBB::class,
   'c' => CCC::class,
];

// $from_input being a, b, or c
if (isset($classes[$from_input])) {
   $obj = new $classes[$from_input];
}
Sign up to request clarification or add additional context in comments.

5 Comments

this is less dynamic, but working. since i need to hold the "dictionary" for classes. any chance to make it: can i combine the string name (AAA, BBB.... ) with the class definition? $obj = app($from_input . '::class'); not working.
@aleXela, that would defeat the purpose of this answer, defensive programming. It's pretty insecure to allow a user to define the class to instantiate. ::class is just a keyword that gives the full name of the class, you shouldn't use ::class as a string like in your example.
i know, i can work on backend to make it more secure. can you please advice how to accomplish it? thanks a lot
a totally agree, but my nature demands me to know how to do it even i will not use it. ))
The problem is the import from use is not going to be evaluated at runtime. You'd need to use the full path to the class: 3v4l.org/7ABSE
1

You could invoke the IoC container which will build you the object with any injected dependencies.

$obj = app()->make($from_input)

or simply

$obj = app($from_input)

6 Comments

nope. $cat = 'AAA'; $obj = app($cat); dd($obj); Gives Class AAA not found.
It's probably a namespace issue, in your example, you included use AAA; so it should be found. Maybe AAA is not properly namespaced.
no, namespace is ok. also if i use it app(AAA::class) working well
this one doesnt work, BUT: $test = 'AAA'; dd(app("Mishai\Sitemanager\Models\\{$test}")); does. Thanks! ))
dd((app("Mishai\Sitemanager\Models\\{$test}"))::get()); this one also after:: where and other methods also working. thanks again
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.