简体   繁体   中英

Call-time pass-by-reference warning

    function heaviside(&$value, $key, &$array)
    {
            if($key > 0)
            $value = $array[$key-1].$array[$key];
    }

    function test_heaviside()
    {
            for($i=0; $i<10; $i++)
            {
                    $array[$i] = $i;
            }
            array_walk($array, 'heaviside', &$array);
            print_r($array);
    }

    test_heaviside();

My problem is that the above code will generate this warning:

PHP Warning: Call-time pass-by-reference has been deprecated - argument passed by value; If you would like to pass it by reference, modify the declaration of array_walk(). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file. However, future versions may not support this any longer.

And if I remove & in &$array in my call to array_walk, this function will not return this correct result. In the first case, where it works, it returns this result:

 [0] => 0 [1] => 01 [2] => 012 [3] => 0123 [4] => 01234 [5] => 012345 [6] => 0123456 [7] => 01234567 [8] => 012345678 [9] => 0123456789 

Whereas if I remove & it returns:

 [0] => 0 [1] => 01 [2] => 12 [3] => 23 [4] => 34 [5] => 45 [6] => 56 [7] => 67 [8] => 78 [9] => 89 

I need help understanding this or simply to find a solution other than changing .ini.

From the php manual about references

Note: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.

This means that you can not tell an argument to be a reference. Only the function definition can do this. If you look at the array_walk manual page you see that only the first argument is a reference, and the last cannot be.

So in the end, what you want is deprecated. You can either

  • change the ini (which you don't want to)
  • downgrade your php version
  • remove the warning by setting the error level lower.
  • write your own array_walk function that does take a reference as 3rd parameter

You're abusing array_walk here -- your callback function isn't actually returning the new value. array_walk is intended to work with one and only one value from the target array, and can not work with anything by reference.

You can achieve the effect you're looking for by using a simple for loop:

// Set up the array.
    $array = array();
    for($i = 0; $i < 10; $i++)
        $array[$i] = $i;
// Process it, starting at the second element
    for($i = 1; $i < count($array); $i++)
        $array[$i] = $array[$i - 1] . $array[$i];
    print_r($array);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM