PHP匿名函数变量作为参考 [英] PHP anonymous function variable as reference
问题描述
在使用 Laravel 框架时,更具体地说 - 表单宏,我偶然发现了一个奇怪的错误.
While working with Laravel framework, more specific - Form macros, I stumbled upon a weird error.
起初,我认为 Laravel 有问题,但后来我断章取意:
At first, I thought it's something wrong with Laravel, but then I took everything out of context:
<?php
// placeholder function that takes variable as reference
$function = function(&$reference)
{
// append to variable
$reference = $reference . ':' . __METHOD__;
};
// test with straight call
$variable = 'something';
$function($variable);
echo $variable;
// test with call_user_func(), that gets called in Laravels case
$variable = 'something'; // reset
call_user_func($function, $variable);
echo $variable;
虽然第一次调用 $function
正常执行,但第二次尝试使用 call_user_func()
,产生(摘自 Codepad):
While the first call to $function
executes properly, the second try with call_user_func()
, produces (excerpt from Codepad):
Warning: Parameter 1 to {closure}() expected to be a reference, value given
PHP Warning: Parameter 1 to {closure}() expected to be a reference, value given
在写这篇文章时,我想到了call_user_func_array()
:fiddle herea>,但产生了同样的错误.
While writing this, I thought about call_user_func_array()
: fiddle here, but the same error is produced.
我对引用有什么误解还是这是 PHP 的错误?
Have I got something wrong about references or is this a bug with PHP?
推荐答案
我认为这是 PHP 的错误,尽管从技术上讲它是 call_user_func
的错误.文档确实提到了这一点,但可能不是很有启发性:
I would call this a bug with PHP, although it's technically a bug with call_user_func
. The documentation does mention this, but perhaps not in a very enlightening way:
注意call_user_func()
的参数不是通过参考.
Note that the parameters for
call_user_func()
are not passed by reference.
说call_user_func()
的参数不是通过引用传递的可能更清楚(但请注意,从技术上讲,根本没有必要说什么;此信息也嵌入在函数签名中).
It would be perhaps clearer to say that the arguments to call_user_func()
are not passed by reference (but note that technically it's not necessary to say anything at all; this information is also embedded in the function signature).
无论如何,这意味着当 call_user_func
最终调用其目标可调用对象时,ZVAL
(所有类型值的 PHP 引擎内部数据结构)传递的参数没有被标记为being-a-reference";闭包在运行时检查并抱怨,因为它的签名说参数必须是一个引用.
In any case, this means is that when call_user_func
finally gets to invoking its target callable, the ZVAL
(PHP engine internal data structure for all types of values) for the argument being passed is not marked as "being-a-reference"; the closure checks this at runtime and complains because its signature says that the argument must be a reference.
在 PHP <5.4.0 可以通过使用调用时按引用传递来解决此问题:
In PHP < 5.4.0 it is possible to work around this by using call-time pass by reference:
call_user_func($function, &$variable);
但是这会产生一个 E_DEPRECATED
警告,因为调用时传递引用是一个不推荐使用的功能,并且会在 PHP 5.4 中导致致命错误,因为该功能已被完全删除.
but this produces an E_DEPRECATED
warning because call-time pass by reference is a deprecated feature, and will flat out cause a fatal error in PHP 5.4 because the feature has been removed completely.
结论:以这种方式使用call_user_func
没有什么好方法.
Conclusion: there is no good way to use call_user_func
in this manner.
这篇关于PHP匿名函数变量作为参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!