一般的想法是这样的:
test
$commands
test::$commands
是key => Callback
对所有这些都考虑过了,我应该写下这个:
$cmdkey
然而,这样做会产生:
PHP注意:未定义的变量:$命令
PHP致命错误:函数名称必须是字符串
我这样解决了这个问题:
self::$commands[$cmdkey]($argument);
在解除引用之前,这是一种反吹,但在PHP中却是......
我是否疯了,或者我确实在PHP解析器中发现了一个错误?
答案 0 :(得分:3)
看起来像是
test::$commands[$cmdkey](foo)
被解释为
test::($commands[$cmdkey])(foo)
即。首先获取$commands[$cmdkey]
包含的内容,并将其用作test
中的函数名称。请注意,只有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
)
)
)