Search code examples
phparraysforeachreferenceunset

Why the temporary variable needs in changing array elements and why it needs to be unset at the end?


Consider below code snippet which changes(convert the values to uppercase) the values of the array directly by passing them by reference.

<?php
  $colors = array('red', 'blue', 'green', 'yellow');

  foreach ($colors as &$color) {
    $color = strtoupper($color);
  }
  unset($color); /* ensure that following writes to
  $color will not modify the last array element */

  print_r($colors);

?>

Output :

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

I've not understood the code above at all. I've few doubts regarding the above code as follows :

  1. I didn't understand this statement at all $color = strtoupper($color); from inside a foreach loop. Why the temporary variable $color is used and in the function strtoupper() why the reference &$color is not passed and only $color is passed?
  2. Why the variable $color has been unset? What did that contain inside before unsetting?
  3. What's the meaning of the comment "ensure that following writes to $color will not modify the last array element" as the last element from array i.e. yellow is also getting modified?

In short please explain me what's happening out there in the code from foreach loop in a step-by step manner.

Please someone answer my doubts.

Note : The above code example has been taken from the PHP Manual's Array chapter.


Solution

  • This is defensive programming at work here.

    On each iteration of the foreach() loop, a reference to the current item value is created in the $color variable, allowing to write a new value to it. When the iteration is over though, the $color variable still contains a reference to the last array item's value, allowing a programmer reusing the $color variable for writing to update that item in the array, which is probably not the intended result. unset()ting the variable after the loop destroys the reference and avoids that risk.

    Building on top of your example :

    <?php
    $colors = array('red', 'blue', 'green', 'yellow');
    
    foreach ($colors as &$color) {
      $color = strtoupper($color);
    }
    //unset($color); 
    /* ensure that following writes to
    $color will not modify the last array element */
    
    print_r($colors);
    $color='hello';
    print_r($colors);
    

    Outputs :

    Array
    (
        [0] => RED
        [1] => BLUE
        [2] => GREEN
        [3] => YELLOW
    )
    Array
    (
        [0] => RED
        [1] => BLUE
        [2] => GREEN
        [3] => hello
    )
    

    https://eval.in/897010