Alternative toeach follow link

I ended up with a case where values ​​in foreach are passed by reference to modify an element, and then at a later stage in the code, the same array is looped again to do some calculations, but this time the elements are passed by value. The problem is that PHP stores a reference to the last element in the array in the first foreach and then overwrites that element when the next foreach runs if the local variable has the same name.

Sample code:

<?php
$a = array("a" => "foo");
$b = array("b" => "bar");

$x = array($a, $b);

foreach ($x as &$y) {}

print_r($x);

foreach ($x as $y) {}

print_r($x);
?>

      

This will give

Array
(
    [0] => Array
        (
            [a] => foo
        )

    [1] => Array
        (
            [b] => bar
        )

)
Array
(
    [0] => Array
        (
            [a] => foo
        )

    [1] => Array
        (
            [a] => foo
        )

)

This absurdity is pointed out in the PHP manual

Warning The reference to the value $ and the last element of the array remain even after the foreach loop. It is recommended to destroy it with unset ().

Indeed, using it unset($y)

will solve the problem. But this is very fragile and you cannot rely on a coder who always remembers to turn off a variable whose scale is not obvious. So my question is, are there any good foreach-pass-by-reference alternatives that obviate the need to subsequently unset the variable?

+3


source to share


2 answers


You can use array_walk()

:

array_walk($x, function(&$y) {
    /* ... */
});

      



This makes the reference $y

local to the scope of the callback function so that the cancellation is automatic.

+3


source


You can use ASSOCIATIVE (indexed) foreach:

foreach ($x as $index=>$y)
{
 if ($y=='remove') {unset($x[$index]);}
}

      



This way you can easily change the original elements of the array ...

+2


source







All Articles