编程语言
首页 > 编程语言> > PHP 5.5中的半复杂解引用

PHP 5.5中的半复杂解引用

作者:互联网

总的想法是这样的:

>我有一个课堂测试
>该类具有公共静态属性$commands
> test :: $commands是一个键数组=>回调对
>我有一个保存在$cmdkey中的密钥

考虑到所有这些,我应该可以这样写:

self::$commands[$cmdkey]($argument);

但是,这样做会产生:

PHP Notice: Undefined variable: $commands
PHP Fatal error: Function name must be a string

我这样做可以解决此问题:

$callback = self::$commands[$cmdkey];
$callback($argument);

尽管在PHP中取消引用是一种回弹,但是…

我会发疯还是实际上在PHP解析器中发现错误?

解决方法:

看起来像

test::$commands[$cmdkey](foo)

被解释为

test::($commands[$cmdkey])(foo)

即首先获取$commands [$cmdkey]包含的内容,并将其用作测试中的函数名称.注意,只是test :: $commands [$cmdkey]正常绑定.

考虑:

class test {
    public static $commands = array('x' => 'strlen');

    public static function other() {
        print 'here!';
    }
}

$cmdkey = 'x';

$commands = array('x' => 'other'); // *

print test::$commands[$cmdkey]('abc');

如果您将*注释掉,您将获得

Notice: Undefined variable: commands...
Fatal error: Function name must be a string...

可悲的是,http://www.php.net/manual/en/language.operators.precedence.php缺少::,因此很难说出这种行为是否是故意的,但这绝对是违反直觉的.

这就是PHPParser所说的:

$code = <<<'EOF'
<?php test::$commands[123](456); ?>
EOF;

$parser = new PhpParser\Parser(new PhpParser\Lexer);
$stmts = $parser->parse($code);
$nodeDumper = new PhpParser\NodeDumper;
print $nodeDumper->dump($stmts);

结果:

0: Expr_StaticCall(
    class: Name(
        parts: array(
            0: test
        )
    )
    name: Expr_ArrayDimFetch(
        var: Expr_Variable(
            name: commands
        )
        dim: Scalar_LNumber(
            value: 123
        )
    )
    args: array(
        0: Arg(
            value: Scalar_LNumber(
                value: 456
            )
            byRef: false
            unpack: false
        )
    )
)

标签:php-5-5,php
来源: https://codeday.me/bug/20191121/2052783.html