为什么 PHP 允许在一种情况下将文字传递给按引用传递参数,而在其他情况下则不允许


Why does PHP allow passing a literal to a pass-by-reference parameter in one case but not others?

函数array_shift()通过引用接受一个参数。传递数组文本会导致致命错误:

$ php -r 'var_export(array_shift(array("Test #0"((;';回波

致命错误:只能在第 1 行的命令行代码中通过引用传递变量

此操作按预期失败。但是,当使用 call_user_func_array 调用函数时,PHP 的行为很奇怪:

<?php
var_export(call_user_func_array("array_shift", array(array("Test #1"))));
echo "'n";
$arg1 = array("Test #2");
var_export(call_user_func_array("array_shift", array($arg1)));
echo "'n";
$args = array(array("Test #3"));
var_export(call_user_func_array("array_shift", $args));
echo "'n";

执行时:

$ php 测试.php

"测试 #1">

警告:array_shift(( 的参数 1 应为引用,值在第 6 行的/Users/kcc/test.php 中给出 零

警告:array_shift(( 的参数 1 应为引用,值在第 10 行的/Users/kcc/test.php 中给出 零

call_user_func_array()不会触发致命错误是可以理解的,但是为什么第一个表单工作正常?

来自 call_user_func_array(( 文档:

在 PHP 5.4 之前,param_arr 中引用的变量通过引用传递给函数,而不管函数是否期望通过引用传递相应的参数。这种形式的调用时间通过引用传递不会发出弃用通知,但它仍然被弃用,并在 PHP 5.4 中删除。此外,这不适用于支持函数签名的内部函数。当函数期望参数通过引用时,按值传递会导致警告并具有call_user_func()返回FALSE(但是,引用计数 = 1 的传递值有一个例外,例如在文本中,因为这些值可以转换为引用而不会产生不良影响 - 但也不会写入该值有任何影响 - ;不要依赖此行为, 但是,由于引用计数是实现细节,并且此行为的合理性值得怀疑(。

(强调我的(

从 PHP 5.4 开始,call_user_func_array() 通过值将其所有参数传递给指定的$callback,除了上面手动引用中粗体的异常情况。

Test #1 中,您有一个纯文本,因此您遇到了文档中描述的特殊异常:文本可以转换为没有不必要的副作用的引用(因为它在完成call_user_func_array()时会被丢弃(。

Test #2Test #3 中,您没有纯文本,并且由于在内部,array_shift被定义为通过引用获取其参数,因此call_user_func_array()引发上述警告。


在 PHP 7 中,Test #1是"固定的",现在正确地发出警告。