tags:

views:

101

answers:

4

Quick question.

I'm new to php and got confused with when to use the unset function. Should I unset everything I set or only when I want to guarantee it gets unset now?

Cheers, Diogo

+2  A: 

There's a garbage collector in php, so you may use unset just in case you want to make sure your object / var is destroyed. It's usefull to make sure a $SESSION is destroyed for example.

Guillaume Lebourgeois
be careful using unset with Sessions though - "Do NOT unset the whole $_SESSION with unset($_SESSION) as this will disable the registering of session variables through the $_SESSION superglobal" http://fr.php.net/session_unset
seengee
+1  A: 

You should only use unset if you want to gurantee that it is deleted from memory. This could be usefull if you process / manipulate / create a bunch of images or something really memory consuming.

Hippo
Although if you're creating images with something like imagick or gd you'd be much better off using their respective destruction functions.
Joonas Trussmann
Not at all, unset() doesn't free the memory reserved by the variable. The variable is just unset and the garbage collector *might* free the memory. There is no guarantee.
Patrick Allaert
+6  A: 

Most of the time you do not need to bother about unsetting. PHP will handle unused variables for you. However, there is certain situations, for instance looping, where it helps reduce memory usage. Consider:

for($i=0;$i<3;$i++) {
    $str = str_repeat("Hello", 10000);
    echo memory_get_peak_usage(), PHP_EOL;
}

This will output something like

375696
425824
425824

At the first iteration $str is still empty before assignment. On the second iteration $str will hold the generated string though. When str_repeat is then called for the second time, it will not immediately overwrite $str, but first create the string that is to be assigned in memory. So you end up with $str and the value it should be assigned. Double memory. If you unset $str, this will not happen:

for($i=0;$i<3;$i++) {
    $str = str_repeat("Hello", 10000);
    echo memory_get_peak_usage(), PHP_EOL;
    unset($str);
}

// outputs something like
375904
376016
376016

Most of the time it doesnt matter. But if you do memory intensive work, keep that in mind, because otherwise you might run into memory leaks quickly.

Gordon
Many thanks, great insight! :)
DiogoNeves
I find that this is rarely the case. Normally it's your `$i` that is very large and items your iterating over are small. In that case, using `unset` will slow down the iteration because `unset` costs more CPU than PHP's garbage collection. I believe that most of the time if your using `unset` *your doing it wrong*, because you could use scoping to do a natural unset for you (it also makes your code look less "C"-ish).
Kendall Hopkins
@Kendall Using `unset` has no speed impact on your code and *scoping* wont help. Also, I find it impossible to say what a loop *normally* iterates over. It's not like image batch processing or iterating large recordsets or object graphs is an uncommon thing to do. Such an argument also misses the point. It's what you do inside the loop. Freeing the memory in the above example would directly affect how many concurrent requests the server can handle before it runs out of memory. True, not everyone needs this, but then again, I never said `unset` all the time, but in *certain situations*.
Gordon
@Gordon The mentioned case is an abnormal case. While it's true that PHP may spike in it's memory usage during the execution of the assignment line, most cases that would case that to be an issue (image processing), would spend a very small % of the time actually running that line compared to the rest of the for loop. Examples like this, is like optimizing PHP by passing data by reference because it saves memory. It's poor practice in high level languages to micro-manage such low level processes. Reference - http://stackoverflow.com/questions/3425848/calling-unset-in-php-script/3425916#3425916
Kendall Hopkins
@Kendall One of us is not getting the point, so I suggest to agree to disagree then.
Gordon
+1  A: 

There is another case when unset() is recommended - foreach loops with references (example from PHP Manual):

$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element

$value = 10; // Without unset() this will change last value of the $arr
Alexander Konstantinov