PHP匿名函数变量作为参考

PHP匿名函数变量作为参考

本文介绍了PHP匿名函数变量作为参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用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匿名函数变量作为参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:07