-----Original Message-----
From: Shawn McKenzie [mailto:nos...@mckenzies.net] 
Sent: 23 July 2009 02:36 PM
To: php-general@lists.php.net
Subject: Re: [PHP] Re: unsetting a referenced parameter in a function

Tom Worster wrote:
> On 7/22/09 6:09 PM, "Shawn McKenzie" <nos...@mckenzies.net> 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;
  $arg = 'meaning';

$a = 0;


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:

function foo() {
  global $a;
  $a = 42;
  $a = 'meaning';

$a = 0;

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
  $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;
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.


PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to