Я обнаружил какое-то странное поведение PHP, мне интересно, может ли кто-нибудь объяснить мне, почему некоторые части этого кода работают, а другие нет.
PHP может создавать новые классы динамически, когда имена классов хранятся в переменных. И это прекрасно работает, так как я использую современную версию PHP (5.5.28). Но я обнаружил странное поведение, которое не совсем понимаю.
Проблема возникает, когда имя класса хранится в свойстве какого-либо объекта. В этом случае статические функции нельзя вызывать для динамического класса:
$this->dynClass::SomeFunction()
не удается и ($this->dynClass)::SomeFunction()
тоже не получается. тем не мение $instance = new $this->dynClass
работает. Так что если мне нужно вызвать статический метод на $this->dynClass
Я должен создать локальную переменную, хранящую ту же строку: $tmp = $this->dynClass
, И тогда я могу позвонить $tmp::SomeFunction()
Я действительно не понимаю этого. Может ли это быть ошибкой? Пожалуйста, кто-нибудь объяснит мне.
Вот мой пример кода:
<?php
class MyClass {
static function SomeFunction($name){
echo "Hello $name\n";
}
}
MyClass::SomeFunction("World"); //Works fine as it should, prints Hello World
$firstInstance = new MyClass;
$firstInstance::SomeFunction("First"); //prints hello first, no problem
//here comes the interesting part
$dynClass = "MyClass";
$dynClass::SomeFunction("Dynamic"); //Yeah, it works as well
$secondInstance = new $dynClass;
$secondInstance::SomeFunction("Second"); //Hello Second. Fine.
//And here comes the part that I don't understand
class OtherClass {
private $dynClass = "MyClass";
public function test(){
$thirdInstance = new $this->dynClass; //WORKS!
$thirdInstance::SomeFunction('Third'); //Hello Third
//BUT
$this->dynClass::SomeFunction("This"); //PHP Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
//OK, but then this one should work:
($this->dynClass)::SomeFunction("This"); //same error. WHY??
//The only solution is creating a local variable:
$tmp = $this->dynClass;
$tmp::SomeFunction("Local"); //Hello Local
}
}
$otherInstance = new OtherClass;
$otherInstance->test();
?>
Перед Единый переменный синтаксис, Переменный синтаксический анализ php был в основном большим количеством угловых случаев.
В частности, некоторые операции, такие как ::
где не поддерживается на (...)
выражения.
Две ошибки, с которыми вы столкнулись, являются примерами этого свободно определенного и несовместимого парсера переменных.
Других решений пока нет …