调用类名存储为实例变量的静态方法


Call static method with class name stored as instance variable

考虑这个脚本

class B
{
    static public function hi() { echo "hi'n"; }
}
class A
{
    private $name = 'B';
    public function __construct()
    {
        // This doesn't parse
        // $this->name::hi();
        // But this works fine
        $class = $this->name;
        $class::hi();
    }
}
new A();

你知道我如何/如果我能得到第一个例子$this->name::hi();来解析和工作吗?

Zend PHP解析器的当前实现仅支持直接对类名或变量进行的静态方法调用。语法如下:

%token T_PAAMAYIM_NEKUDOTAYIM ":: (T_PAAMAYIM_NEKUDOTAYIM)"
function_call:
    name argument_list
        { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
|   class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
        { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
|   variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
        { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
|   callable_expr argument_list
        { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }

来源:https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L890

考虑到在您当前的情况下,您需要在类a中使用类b的方法,以这种方式处理它似乎非常违反直觉。此外,调用另一个类的方法的可用性根本不存在,您需要使用:

call_user_func(array($this->name, 'hi'));

一种方法是简单地要求B类作为a类的构造函数的依赖项:

class B
{
    static public function hi() { echo "hi'n"; }
}
class A
{
    private $b;
    public function __construct(B $b)
    {
        $b::hi();
    }
}
new A(new B);

这可能是你所寻找的最接近于一行的方法。