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

C. E.
  • 10,297
  • 10
  • 53
  • 77

2 Answers2

4

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
Nanne
  • 64,065
  • 16
  • 119
  • 163
2

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);
Charles
  • 50,943
  • 13
  • 104
  • 142
  • 1
    Don't use count() in the loop declaration! Count() is relatively expensive and it will be executed every time round the loop, making it slow. Store the count to a variable first and use that instead. – GordonM Mar 03 '11 at 08:19
  • 1
    Yeah, I was lazy when writing it. :) – Charles Mar 03 '11 at 16:18