Page 2 of 2
Posted: Tue Jun 13, 2006 3:18 am
by Chris Corbyn
Maugrim_The_Reaper wrote:Here's an example I came across...
Code: Select all
$a = "test";
$b =& $a;
$c =& $b;
unset( $a );
print( "$b $c" );
$a is the variable containing value "test". $b and $c are references. When you call unset() against $a, $b and $c STILL point to the "test" values which has not been removed from memory. In other words, unset()'ing a variable with references does not remove the value from memory. Since Objects are passed all over an app by reference it makes you wonder if unset() is worth using... Anyone come across anything else?
Code: Select all
<?php
class Test {
public $value = 'I am Test!';
public function __construct() {}
}
class Test2 {
public $test_ref = null;
public function __construct($test_ref) {
$this->test_ref = $test_ref;
}
}
$a = new Test;
$b = new Test2($a);
unset($a);
var_dump($b->test_ref); // Test has survived unscathed
?>
Interesting. So the only real reason to use unset appears to be in terms of logic. Would be worth posting those snippets on the comments for unset at php.net

Posted: Tue Jun 13, 2006 4:52 am
by Maugrim_The_Reaper
I think it defies the obvious logic... unset() destroys the variable - which itself merely points to the actual value in-memory. Destroying the signpost to a town rarely destroys the town in a mini apocalypse. unset() just doesn't seem a straightforward way of reducing/removing memory, there are other variables to consider... At least it explains why NULL is often more effective.
PHP Notes is currently down...once it's back... I didn't see any related notes so took your suggestion. Might get a response or two.
Posted: Tue Jun 13, 2006 8:29 am
by sweatje
Derick Rethans had an article about this in PHP|Arch last summer. Basically each varaiable is stored internally to PHP with a values and a reference count. If you create a reference to the variable, it does not create a new copy of the value, it bumps the reference count. When you unset, it decrements the reference count. The value would not be removed until the reference count was zero, i.e. nobody is looking at it any more.
Posted: Tue Jun 13, 2006 8:44 am
by daou
I think it defies the obvious logic... unset() destroys the variable
I agree. For a language that handles all memory management, the existence of unset() seems questionable. From what I've understood it's not a function but a statement that flags a variable for destruction at the end of the script. Which defeats the whole purpose because PHP does this anyway.
But it's possibly better use unset() instead of NULL in any case. Take for example a 2D array:
Code: Select all
<?php
$foo = array();
$bar = array();
$bar['a'] = 0;
$bar['b'] = 1;
$foo[0] = $bar;
unset($bar);
$bar['c'] = 2;
$bar['d'] = 3;
$foo[1] = $bar;
?>
If one was to continue in the same manner to make a huge array, calling unset would allow PHP to free the memory associated with the $bar arrays when it thinks is best and thus possibly reducing execution time. Whereas NULL would force the memory associated with $bar to be cleared right away. Does this make sense?
Posted: Tue Jun 13, 2006 9:03 am
by daou
Basically each varaiable is stored internally to PHP with a values and a reference count. If you create a reference to the variable, it does not create a new copy of the value, it bumps the reference count. When you unset, it decrements the reference count. The value would not be removed until the reference count was zero, i.e. nobody is looking at it any more.
So the originally declared variable is itself already a reference.
Posted: Tue Jun 13, 2006 9:24 am
by Maugrim_The_Reaper
I agree. For a language that handles all memory management, the existence of unset() seems questionable. From what I've understood it's not a function but a statement that flags a variable for destruction at the end of the script. Which defeats the whole purpose because PHP does this anyway.
Let's all agree its badly documented - a more in-depth explanation would avoid a lot of confusion. Obviously unset() may free up memory (for overwriting I assume) but this is an indirect result of the operation - not a direct guaranteed consequence.
So the originally declared variable is itself already a reference.
Almost, but to all intensive purposes...yes. A variable points to a value held in memory. When you create a "reference", you are creating a variable holding a new reference to the same value (not to the original "variable" - an important distinction). This explains why unsetting any variable has no effect on any references. However, setting such an origin or reference variable to NULL effects them all, since a NULL assignment is directed at the value held in memory.
It's a bit confusing...eh?
I agree. For a language that handles all memory management, the existence of unset() seems questionable. From what I've understood it's not a function but a statement that flags a variable for destruction at the end of the script. Which defeats the whole purpose because PHP does this anyway.
It destroys the variable - just not the value the variable was referencing in memory. Remember a variable is just a signpost, destroying the signpost will not affect what its pointing at directly (i.e. the value in memory). (Though as this thread evidences, it will confuse travellers on the road...).
Consider a valid use case. You create a variable. You create several references. You need to re-assign the original variable but not affect the subsequent created references. In this case unset() is your saviour - you can destroy the original variable and assign it a new value, all without affecting other references to the original value.
Posted: Tue Jun 13, 2006 11:56 am
by Christopher
Maugrim_The_Reaper wrote:Let's all agree its badly documented - a more in-depth explanation would avoid a lot of confusion. Obviously unset() may free up memory (for overwriting I assume) but this is an indirect result of the operation - not a direct guaranteed consequence.
Actually I think an in-depth explanation would probably do more harm than good for a couple of reasons. First, unset() is not a problem for anyone in this discussion. It was only brought up because a C programmer wanted to use it like free() -- to which the short (but good enough) answer is that it doesn't work that way in PHP. I think most PHP programmers intuitively do not do any memory management until they have a situation where they are doing something like loading files into buffers or repeatedly creating large classes. Finally, the implementation of unset() has probably changed over the year and we have been blissfully unaware of the improvements because the problem has been abstracted for us.
Posted: Wed Jun 14, 2006 8:11 am
by daou
Ok, so to sum up:
C->PHP == heavy duty brain rewiring
