使用静态函数的PHP动态类名

3

我发现了一些奇怪的PHP行为,我想知道为什么这段代码的某些部分起作用,而另一些部分则无法正常工作。

当类名存储在变量中时,PHP可以在运行时动态地创建新的类。如果我使用现代版的PHP(5.5.28),它能够很好地工作。但是,我发现了一些奇怪的行为,我真的不明白其中的原因。

问题出现在当类名被存储在某个对象的属性中时。在这种情况下,动态类上不能调用静态函数: $this->dynClass::SomeFunction()($this->dynClass)::SomeFunction()都会失败。然而,$instance = new $this->dynClass却可以工作。所以,如果我需要调用$this->dynClass的静态方法,我必须创建一个存储相同字符串的本地变量:$tmp = $this->dynClass。然后,我就可以调用$tmp::SomeFunction()

我真的不理解这个问题。这可能是一个bug吗?请有人向我解释一下。

以下是我的示例代码:

<?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();

?>

2
我不理解PHP内部机制,所以无法告诉您确切原因,但看起来在PHP 7中已经修复。使用当前的PHP 7 beta进行实时示例:http://codepad.viper-7.com/CfJtD3 修复的RFC:https://wiki.php.net/rfc/uniform_variable_syntax - Steve
1个回答

1
统一变量语法之前,php的变量解析基本上是一堆特例。
特别是某些操作,比如::,不支持(...)表达式。
你遇到的这两个错误就是这个松散定义和不一致的变量解析器的例子。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接