8

I am playing around with arrays in PHP, and I've get confused about unset() function, here's the code:

<?php

$array = array(1, 2, 3, 4);
foreach ($array as $value) {
    $value + 10;
}
unset($value);
print_r($array);

?>

Is it necessary to unset($value), when $value remains after foreach loop, is it good practice?

kronberger
  • 85
  • 1
  • 4
  • 1
    @nogad - incorrect, it exists within the scope of the function in which it is defined – Mark Baker Nov 06 '17 at 00:28
  • From PHP reference - Beginner to Intermediate Book – kronberger Nov 06 '17 at 00:28
  • guess i have never checked, as i have never wanted to use it, must be the last value from the loop. so in this case "4" you could remove that from memory, but not likely to be a big deal –  Nov 06 '17 at 00:29
  • @kronberger - you don't, although if you defined it "by reference" (e.g. `foreach ($array as &$value) {` it can cause unexpected problems for the unwary, especially if you iterate through that array a second time – Mark Baker Nov 06 '17 at 00:29
  • 2
    BTW: `$value + 10;` ? is doing nothing –  Nov 06 '17 at 00:31
  • Possible duplicate of [Are PHP variables declared inside a foreach loop destroyed and re-created at each iteration?](https://stackoverflow.com/questions/13626812/are-php-variables-declared-inside-a-foreach-loop-destroyed-and-re-created-at-eac) – sg- Nov 06 '17 at 00:34
  • Tnx for answers :) – kronberger Nov 06 '17 at 00:37
  • It's not necessary to unset `$value`. Neither is it a best practice one way or the other. That said, if you want to avoid the question altogether, you can use `array_map()` instead; e.g: `$multipliedByTen = array_map(function ($value) { return $value + 10; }, $array);` - assuming you meant to create a new array of values multiplied by ten in your example above (as @nogad pointed out the loop in your example isn't doing anything permanent) – Darragh Enright Nov 06 '17 at 00:38

4 Answers4

33

I know this post is old, but I think this info is very important: You asked:

Is it necessary to unset($value), when $value remains after foreach loop, is it good practice?

It depends on wheter you iterate by value or by reference.

First case (by value):

$array = array(1, 2, 3, 4);
foreach ($array as $value) {

    //here $value is 1, then 2, then 3, then 4

}

//here $value will continue having a value of 4
//but if you change it, nothing happens with your array

$value = 'boom!';
//your array doesn't change.

So it's not necessary to unset $value

Second case (by reference):

$array = array(1, 2, 3, 4);
foreach ($array as &$value) {

    //here $value is not a number, but a REFERENCE.
    //that means, it will NOT be 1, then 2, then 3, then 4
    //$value will be $array[0], then $array[1], etc

}

//here $value it's not 4, it's $array[3], it will remain as a reference
//so, if you change $value, $array[3] will change

$value = 'boom!'; //this will do:  $array[3] = 'boom';
print_r ($array); //Array ( [0] => 1 [1] => 2 [2] => 3 [3] => boom! )

So in this case it is a good practice to unset $value, because by doing that, you break the reference to the array. Is it necessary? No, but if you don't do it, you should be very careful.

It can lead to unexpected results like this one:

$letters = array('a', 'b', 'c', 'd');

foreach ($letters as &$item) {}
foreach ($letters as  $item) {}

print_r ($letters); //output: Array ( [0] => a [1] => b [2] => c [3] => c )
// [a,b,c,c], not [a,b,c,d]

This is also valid for PHP 7.0

Same code with unset:

$letters = array('a', 'b', 'c', 'd');

foreach ($letters as &$item) {}
unset ($item);
foreach ($letters as  $item) {}

print_r ($letters); //output: Array ( [0] => a [1] => b [2] => c [3] => d )
// now it's [a,b,c,d]

I hope this can be useful for someone in the future. :)

  • 7
    This should have been the accepted answer. Inexperienced devs might mess up if they don't understand the value/reference thingy. – nickpapoutsis Feb 22 '20 at 10:31
  • 1
    Sitenote: (Inexperienced) devs should use PHP Inspections EA (or any other static code analyser?) and they will get notified about that possible issue. If multiple devs work on one project, the sooner or later someone will forget this little unset thing (or others) and then it's good to have the IDE watch over it. – aProgger Mar 17 '21 at 08:15
  • This answer definitely should be the accepted one - as an answer, which explains whole aspect of unset() after different foreaches – Green Joffer Apr 23 '21 at 11:01
2

There's no need to use unset in the current context that you are using it. unset will simply destroy the variable and its content.

In the example you are giving, this is looping through an array creating $value, then you are unsetting that variable. Which means it no longer exists in that code. So that does absolutely nothing.

To visuallize what I am talking about look at this example:

$value = 'Hello World';
echo $value;
unset($value);
echo $value;

The following out will be:

Hello World<br /><b>NOTICE</b> Undefined variable: value on line number 6<br />

So you will first see the Hello World, but after unsetting that variable trying to call it will just cause an error.

To answer your question, you really don't have to unset value; there's no need for it. As the foreach loop is setting a $value of each array() + 10.

Unsetting it will cause the work to be removed, and forgotten.

Sam
  • 2,856
  • 3
  • 18
  • 29
0

One reason I can see to unset $value is to make sure you don't unintentionally use it later in the same script. I just had to deal with a really confusing bug caused by duplicating a few lines from inside one loop into another loop, and it used the final value of $value from the first loop. At least if I have unset it I would have got a useful error message due to trying to access a variable that did not exist.

Jon Green
  • 31
  • 3
-1
<?php
    $array = array(1, 2, 3, 4);
    foreach ($array as &$value) {
        $value = $value + 10;
    }
    unset($value);
    print_r($array);

you leak the "&", maybe.

GYaN
  • 2,327
  • 4
  • 19
  • 39
风声猎猎
  • 1,065
  • 1
  • 7
  • 9