在另一个问题中指出,将PHP函数调用的结果用括号括起来可以将其转换为完整的表达式,从而使以下内容正常工作:
<?php
error_reporting(E_ALL | E_STRICT);
function get_array() {
return array();
}
function foo() {
// return reset(get_array());
// ^ error: "Only variables should be passed by reference"
return reset((get_array()));
// ^ OK
}
foo();
我正在尝试在文档中找到任何明确和无歧义地解释这里正在发生什么的内容。与C++不同,我对PHP语法及其对语句/表达式的处理了解不足,无法自己推导出来。
文档中是否隐藏有关于此行为的信息?如果没有,是否有其他人可以不借助假设来解释它?
更新
我最初发现这个EBNF试图表示PHP语法,并尝试自己解码我的脚本,但最终放弃了。
然后,使用phc
生成两个foo()
变体的.dot
文件,我使用以下命令为两个脚本生成AST图像:
$ yum install phc graphviz
$ phc --dump-ast-dot test1.php > test1.dot
$ dot -Tpng test1.dot > test1.png
$ phc --dump-ast-dot test2.php > test2.dot
$ dot -Tpng test2.dot > test2.png
在这两种情况下,结果完全相同:
Array()
用大写字母 A?据我所知,语言结构应该写作array()
。 - knittlthis
关键字的原因是,只有变量或者单一返回引用的函数才可以作为“reset”的正确输入。变量显然总是通过引用来工作,这就让我们只能使用函数调用。但由于可能存在像$variablewithafunctionname()
这样的情况,所以只有在执行时才会检查函数调用是否满足条件。如果()
使reset
不报错...那么在reset
获取输入时,它就是一个引用(refcount > 1),这意味着(get_array())
表达式在内存中留下了一些zval。 - Wrikkenreturn reset((get_array()?:0));
)已经在编译时出现,措辞更加严厉:“致命错误:只有变量可以通过引用传递”(如果函数返回引用,则一切都很好)。在发出严格通知之前会检查许多标志,我嗅到了其中的某些东西,但我对PHP内部不太了解:php-trunk/Zend/zend_vm_execute.h line 10853~ - hakre