-----Original Message----- From: Shawn McKenzie [mailto:nospam@xxxxxxxxxxxxx] Sent: 23 July 2009 02:36 PM To: php-general@xxxxxxxxxxxxx Subject: Re: Re: unsetting a referenced parameter in a function Tom Worster wrote: > On 7/22/09 6:09 PM, "Shawn McKenzie" <nospam@xxxxxxxxxxxxx> wrote: > >> Tom Worster wrote: >>> though the manual is perfectly clear that this should be expected, i >>> was a bit surprised that the result of the following is 42 >>> >>> <?php >>> function foo(&$a) { >>> $a = 42; >>> unset($a); >>> $a = 'meaning'; >>> } >>> foo($a); >>> print("$a\n"); >>> ?> >>> >>> normally i would expect unset() to free some memory. but in this >>> example it doesn't and has a different behavior: it releases foo's >>> reference to the global $a, allowing the next line to define a local $a. >>> >>> i think i'd have preferred compile error. >>> >>> >> Well, you unset the reference and then you assigned 'meaning' to a >> local function variable $a. Why would you get a compile error? > > when you state it in those terms (which are clearly correct) i wouldn't. > > but if the way i think is "unset() destroys the specified variables" > (as the manual puts it) then i expect that the specified variable > would be destroyed, not the reference. > > so, as i said, i was a bit surprised when the variable wasn't destroyed. > once i understood what was happening, i thought it a bit confusing to > have such scope-dependent differences in behavior of a language element. > > It might be easier to understand if you don't use the same var names: function foo(&$arg) { $arg = 42; unset($arg); $arg = 'meaning'; } $a = 0; foo($a); print("$a\n"); -Shawn -- Another way to see it (from Shawn's example): the "&" is an "address of" (reference to) a variable, so function foo(&$arg) creates a local variable $arg pointing to a global variable called $a. Changing the value of local $arg updates the global $a. The unset($arg) removes the local $arg but has no effect on global $a. The next line $arg = 'meaning' creates a new local variable called $arg which has no connection whatsoever with the $arg that was unset - it could just as well have been called $xyz. As Shawn pointed out there's no problem here with scope, you were just confusing yourself by using the same variable name in the function, but it's a separate local variable regardless of what name you give it. A slight variation of your example: <?php function foo() { global $a; $a = 42; unset($a); $a = 'meaning'; } $a = 0; foo($a); print("$a\n"); ?> You get exactly the same result as your example, for the same reason, the only difference is that you obviously can't change the local variable name in the function. A final variation (to drive the point home): function foo(&$arg) { global $a; $a = 42; <== at this point $arg = 42 unset($a); $a = 'meaning'; <== $arg is still 42 $a = &$arg; <== $a now points to same address $arg is pointing to $a = 'of life'; <== $arg now = 'of life' } $a = 0; foo($a); print("$a\n"); <== prints 'of life' Here in function foo() local $arg and local $a are both pointing to the global $a, and changing either of them changes the other (and changes the global variable). After unset($a) only local $arg is pointing to global $a. After $a = &$arg both local variables are again pointing to global $a, and local $a value has therefor obviously changed from 'meaning' to 42. Then after $a = 'of life' both local variables and the global $a is changed to 'of life'. Local $a and global $a have the same names but are different variables. Also, the local $a after unset($a) happens to have the same name as the $a before unset($a) but it's a different variable, it could just as easily been called $b after unset($a). A final point: the "global $a;" in the function doesn't mean it's THE global $a, it just means it's a local variable called $a pointing to (referencing) a global variable with the same name. In PHP it has to be the same name because that's the way the "global" statement works, but it can sometimes create the impression that it's the same variable. Hope I haven't made that as clear as mud. Cheers Arno -- -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php