Reputation: 6369
In Laravel (4 & 5), I am trying to use dynamic class names and then call them directly, but receiving a fatal error if not first storing them in a local string variable.
Assuming I have a basic class:
class SimpleModel {
private $modelName;
function __construct($id) {
$this->modelName = AnotherModel::getName($id);
}
}
Within the methods, I can easily do
$modelName = $this->modelName;
$modelName::find(1);
But I get a fatal error when trying the following:
$this->modelName::find(1);
This triggers a Symfony\Component\Debug\Exception\FatalErrorException
with a message of
syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
Basically the T_PAAMAYIM_NEKUDOTAYIM
is a syntax error generated from the ::
symbol.
Can't wrap my head around why Laravel (or PHP in general) allows dynamic class names when using a local variable (within a method) but not a class variable.
I also tried putting it in a seprate method getModelName()
method but getting the same error.
$this->getModelName()::find(1);
Instanciating a new class every time (new $this->modelName
) is not a good solution.
I was looking into using PHP's Reflection
but not sure how to do it without instanciating a new class every time.
Since it is working when using a local string, it seems as Reflection
might be an over kill.
Upvotes: 1
Views: 2367
Reputation: 24551
This is due to how the PHP parser works (up to PHP 5). The T_PAAMAYIM_NEKUDOTAYIM
token (::
) is only allowed after T_STRING
(that represents a class name, not a string within quotes) or, since PHP 5.3, T_VARIABLE
.
But your code will work in PHP 7, where the parser has been fundamentally reworked (see: https://wiki.php.net/rfc/abstract_syntax_tree)
Demo: https://3v4l.org/sdBss
Upvotes: 2
Reputation: 40909
You can use call_user_func or call_user_func_array to call method of a class, the name of which is stored in object's attribute:
call_user_func(array($this->modelName, 'find'), 1)
OR
call_user_func_array(array($this->modelName, 'find'), array(1))
Upvotes: 1