问题描述
在使用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
时,第二次尝试产生(摘录自键盘):
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
提琴:键盘@ Viper-7
在撰写本文时,我想到了call_user_func_array()
:在这里摆弄,但存在相同的错误产生了.
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?
推荐答案
尽管从技术上讲,它是call_user_func
的错误,但我将其称为PHP的错误.该文档确实提到了这一点,但可能不是很启发性的:
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()
的参数不通过引用传递可能更清楚(但请注意,从技术上讲,根本不需要说什么;该信息也嵌入在功能签名).
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引擎内部数据结构)都不会标记为"-a参考";闭包在运行时会对此进行检查并抱怨,因为其签名表明该参数必须是引用.
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匿名函数变量作为参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!