donglan6967
2015-03-19 17:45
浏览 58
已采纳

使用变量类名和静态方法时出错

Running PHP 5.4, so I wasn't expecting this, but I'm encountering the following error:

Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

Assume you have a variable of stdClass setup as follows:

$this->variable = new stdClass();

$this->variable->other = array('class' => 'helloworld');

Now, assume you want to access a static method of class helloworld:

// Standard call
$x = helloworld::my_static_method();

// Call with variable class name
$x = $this->variable->other['class']::my_static_method();

When calling the above using the variable class name, I receive the parsing error. What's odd, is that if I do the following, no error is presented:

$class = $this->variable->other['class'];

$x = $class::my_static_method();

To me this seems very odd, can anyone think of a reason why the class name isn't resolving correctly when using the first example versus the second?

图片转代码服务由CSDN问答提供 功能建议

运行PHP 5.4,所以我没想到这一点,但我遇到了以下错误:

 解析错误:语法错误,意外'::'(T_PAAMAYIM_NEKUDOTAYIM)
   
 
 

假设您有一个 stdClass 设置如下:

  $ this-> variable = new stdClass(); 
 
 $ this-> variable-> other  = array('class'=>'helloworld'); 
   
 
 

现在,假设您要访问类 helloworld

  //标准调用
 $ x = helloworld :: my_static_method(); 
 
 //使用变量类名调用
 $ x = $ this  - > variable->其他['class'] :: my_static_method(); 
   
 
 

使用变量类名调用上面的内容时,我会收到解析 错误。 奇怪的是,如果我执行以下操作,则不会出现错误:

  $ class = $ this-> variable-> other ['class']; \  n 
 $ x = $ class :: my_static_method(); 
   
 
 

对我来说,这似乎很奇怪,任何人都可以想到为什么班级名称不是' 使用第一个例子与第二个例子时正确解析?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duanmie9741 2015-03-20 10:24
    已采纳

    can anyone think of a reason why the class name isn't resolving correctly when using the first example versus the second?

    The PHP parser does not support such a syntax, and that's merely all. This is because the parser has grown historically. I can't give more reason than that.

    It will be that with PHP 7 you can see some changes on these syntax details working more into your expected direction Uniform Variable Syntax:

    ($variable->other['class'])::my_static_method();
    

    But until then, you can go around that with the help of call_user_func:

    call_user_func([$variable->other['class'], 'my_static_method']);
    call_user_func($variable->other['class'] . '::my_static_method');
    

    Or as you wrote your own, by creating a variable:

    $class = $variable->other['class'];
    $class::my_static_method();
    

    Or even a variable that looks like something different:

    ${(int)!${0}=$variable->other['class']}::my_static_method();
    

    Related Material:

    打赏 评论
  • doupo1865 2015-03-19 20:28

    This doesn't work ($this->variable->other['class']::my_static_method()) as it's essentially using a string as the class name directly. It works when you assign it to a variable first, as it's then being evaluated out as the class name instead.

    You can also look into using ReflectionMethod invocation in order to call the method, in which case you wouldn't have to store the class name in a variable before using it. Here's the docs on that: http://php.net/manual/en/class.reflectionmethod.php and on the invoke method (you pass in NULL to indicate a static method) http://php.net/manual/en/reflectionmethod.invoke.php

    Here are a couple examples of ways to invoke your function:

    class helloworld{
        public static function my_static_method($i = 0){
            echo "Here: ".$i;
        }
    }
    
    class Foo{
        private $variable;
    
        public function __construct(){
            //Create a new class
            $this->variable = new stdClass();
    
            //Create a new property of the class, storing an array
            $this->variable->other = array('class' => 'helloworld');
    
            //Call function statically
            $x = helloworld::my_static_method(1); //Outputs: "Here: 1"
    
            //Store class name in a variable before use
            $class = $this->variable->other['class'];
            $y = $class::my_static_method(2); //Outputs: "Here: 2"
    
            //Using a ReflectionMethod, you can call the function this way, too
            $z = new ReflectionMethod($this->variable->other['class'], 'my_static_method');
            $z->invoke(null, 3); //Outputs: "Here: 3"
        }
    }
    
    //Instantiate new Foo class
    new Foo();
    
    打赏 评论

相关推荐 更多相似问题