PHP anonymous function variable as reference

核能气质少年 提交于 2019-12-08 08:15:30

问题


While working with Laravel framework, more specific - Form macros, I stumbled upon a weird error.

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;

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

Fiddle: Codepad @ Viper-7

While writing this, I thought about call_user_func_array(): fiddle here, but the same error is produced.

Have I got something wrong about references or is this a bug with PHP?


回答1:


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:

Note that the parameters for call_user_func() are not passed by reference.

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).

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.

In PHP < 5.4.0 it is possible to work around this by using call-time pass by reference:

 call_user_func($function, &$variable);

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.

Conclusion: there is no good way to use call_user_func in this manner.




回答2:


This works:

call_user_func_array($function, array(&$variable));



回答3:


I used this code

<?php
$myfunction = function &($arg=3)
{
    $arg = $arg * 2;
    return $arg;
};
echo $myfunction();
?>

Worked like a charm. :)




回答4:


What happens if you do this?

call_user_func($function, &$variable);


来源:https://stackoverflow.com/questions/12839622/php-anonymous-function-variable-as-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!