3 回答

TA贡献1786条经验 获得超11个赞
此行为可以归为bug,因此您绝对不应依赖它。
不会在函数调用中引发消息的(简化)条件如下(请参阅opcodeZEND_SEND_VAR_NO_REF的定义):
参数不是函数调用(如果是,则通过引用返回),并且
该参数可以是引用,也可以具有引用计数1(如果引用计数为1,则将其转换为引用)。
让我们更详细地分析这些。
第一点是正确的(不是函数调用)
由于附加括号,PHP不再检测到该参数是函数调用。
解析非空函数参数列表时,PHP有三种可能性:
一个 expr_without_variable
一种 variable
(A &后跟一个variable,表示已删除的呼叫时按参考传递功能)
仅在编写get_array()PHP时,会将其视为variable。
(get_array())另一方面没有资格variable。这是一个expr_without_variable。
这最终会影响代码的编译方式,即操作码的扩展值SEND_VAR_NO_REF将不再包含flag ZEND_ARG_SEND_FUNCTION,这是在操作码实现中检测到函数调用的方式。
第二点是正确的(参考计数为1)
在某些情况下,Zend Engine允许引用数为1的非引用(期望引用)。这些细节不应暴露给用户,但是不幸的是它们在这里。
在您的示例中,您将返回未从其他任何地方引用的数组。如果是这样,您仍然会收到消息,即第二点将不成立。
因此,以下非常相似的示例不起作用:
<?php
$a = array();
function get_array() {
return $GLOBALS['a'];
}
return reset((get_array()));

TA贡献1806条经验 获得超5个赞
A)要了解这里发生的情况,需要了解PHP对值/变量和引用的处理(PDF,1.2MB)。正如整个文档中所述:“引用不是指针”;而且您只能通过函数的引用返回变量 -别无其他。
在我看来,这意味着PHP中的任何函数都将返回reference。但是某些函数(用PHP内置)需要值/变量作为参数。现在,如果要嵌套函数调用,则内部的将返回一个引用,而外部的将返回一个值。这导致“著名的” E_STRICT错误“仅应通过引用传递变量”。
$fileName = 'example.txt';
$fileExtension = array_pop(explode('.', $fileName));
// will result in Error 2048: Only variables should be passed by reference in…
B)我在问题中链接的PHP语法描述中找到了一行。
expr_without_variable = "(" expr ")"
结合文档中的这句话:“在PHP中,几乎所有您编写的内容都是一个表达式。定义表达式的最简单但最准确的方法是'有值的任何东西'。”,这使我得出以下结论:(5)是PHP中的一个表达式,其结果为值为5的整数。
(因为$a = 5不仅是赋值,而且是一个表达式,其结果为5。)
结论
如果您传递对表达式的引用(...),则此表达式将返回一个值,然后可以将其作为参数传递给外部函数。如果那(我的想法)是正确的,那么以下两行应该等效地起作用:
// what I've used over years: (spaces only added for readability)
$fileExtension = array_pop( ( explode('.', $fileName) ) );
// vs
$fileExtension = array_pop( $tmp = explode('.', $fileName) );
另请参见PHP 5.0.5:致命错误:只能通过引用传递变量;否则,不能进行引用。2005年9月13日

TA贡献1911条经验 获得超7个赞
那么这篇文章是高度投机的。在没有文档的情况下(我已经搜索了一个多小时,并且知道如何使用搜索引擎),这是我能提供的最好的服务。我的想法是,通常以SO-wiki条目的形式为该行为创建一个文档。
- 3 回答
- 0 关注
- 407 浏览
添加回答
举报