PHP匿名函数变量作为参考 [英] PHP anonymous function variable as reference

查看:26
本文介绍了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 正常执行,但第二次尝试使用 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

小提琴:Codepad @ Viper-7

在写这篇文章时,我想到了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆