1

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.

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for explaining this.
1

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))

3 Comments

That works, but still doesn't explain why this is happening. Any idea?
Because it’s simply not supported.
Since PHP 5.3 it is allowed to call static methods and access static attributes using dynamic class names stored in variables, e.g.: $a::foo(), but it stiill doesn't allow what you're trying to do. It's also not clear to me what benefit you see in calling static methods such unusual way.

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.