Re: Re: unsetting a referenced parameter in a function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I think he is confusing the "unset" semantic.
Unset just destroy a variable, but not the content of it.

Take a look at the output of this simple script:
function avoid_global_scope()
{
    $a = 'foo';
    var_dump( get_defined_vars() );
    $b =& $a;
    var_dump( get_defined_vars() );
    unset( $a );
    var_dump( get_defined_vars() );
    unset( $b );
}
avoid_global_scope();

This is the output in my apache2 / php 5.2.6... but yours MUST be the same

array(1) {
  ["a"]=>  string(3) "foo"
}
array(2) {
  ["a"]=>  &string(3) "foo"
  ["b"]=>  &string(3) "foo"
}
array(1) {
  ["b"]=>  string(3) "foo"
}

Note in the second array both variables was converted to references.
But in the third "b" is just a common variable.

This behaviour is cause by how PHP handles the references?


1) $a = 'foo';
Here we have an string 'foo' and a variable "a" which points to the string.

2) $b =& $a;
Now we have anothe variable "b" which refers to _contents_ of variable "a"
Variable "a" is converted to a reference to it contents

3) unset( $a );
When "a" is destroyed only "b" refers to 'foo', PHP handles "b" as a common
var

3) unset( $b );
When "b" is destroyed PHP notes that no one is referencing 'foo'... so, it's
removed too.

Remember... unset destroy variables, not it's content.

class Foo
{
    public static $last;

    function __construct()
    {
        self::$last =& $this;
    }
}

$a = new Foo;

$a = null;
unset( $a );

var_dump( Foo::$last instanceof Foo ); # bool(true)


On Thu, Jul 23, 2009 at 9:35 AM, Shawn McKenzie <nospam@xxxxxxxxxxxxx>wrote:

> 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");
>
>
> --
> Thanks!
> -Shawn
> http://www.spidean.com
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
Martin Scotta

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux