Re: unset() side effects in functions

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

 



On Mon, 2007-04-23 at 14:04 +0300, Robert Enyedi wrote:
> I'm doing some experimenting with the unset() (http://php.net/unset) 
> language construct in a PHP 5.2.1 installation. I did not find any 
> documentation on what happens to an identically named local variable's 
> value after an unset is performed.
> 
> Let me start with this example:
> 
> <?php
> function dostuff() {
> 		$a = 4;
> 		echo ">in function (init): ".$a."<\n";
> 	
> 		global $a;
> /*CHANGEME*/	unset($a);
> 	
> 		echo ">in function (after unset): ".$a."<\n";
> 		$a = 3;
> 		echo ">in function (after local assign): ".$a."<\n";
> }
> 
> $a = 2;
> dostuff();
> echo ">in page: ".$a."<\n";
> ?>
> 
> The output is:
>  >in function (init): 4<
>  >in function (after unset): <
>  >in function (after local assign): 3<
>  >in page: 2<
> 
> So this basically means that the global $a is dereferenced by the 
> unset() call and the local $a gets reinitialized.
> 
> A different thing happens when we replace the /*CHANGEME*/ line with 
> unset using the $GLOBALS[] array (the recommended way of unsetting a 
> global variable from inside a function):
> 
> unset($GLOBALS['a']);
> 
> This time the output is:
> 
>  >in function (init): 4<
>  >in function (after unset): 2<
>  >in function (after local assign): 3<
>  >in page: <
> 
> Notice that after the unset statement the global $a is properly unset 
> BUT the value of the local $a becomes 2, which was the value of the 
> global $a at the function entry point.
> 
> Are these behaviors documented somewhere or should't I rely on these 
> unset() side effects at all in my code?

You are very confused as to what is happening. Unset() is working
properly.

<?php

    function dostuff()
    {
                $a = 4;
                echo ">in function (init): ".$a."<\n";
        
global $a;
/*CHANGEME*/    unset($a);
        
                echo ">in function (after unset): ".$a."<\n";
                $a = 3;
                echo ">in function (after local assign): ".$a."<\n";
    }
?>

Let's break it down...

// create locale variable $a with value 4
$a = 4;

// create reference to global variable $a. This will destroy local
// variable $a and replace it with a reference to $GLOBALS['a']
global $a

// unset local variable $a (reference to $GLOBALS['a']. Now there is
// no variable $a in current scope (attempts to reference non-existent
// variables will return null.
unset( $a )

// create locale variable $a with value 3
$a = 3;

------------------------

Now for the other case...

// create locale variable $a with value 4
$a = 4;

// create reference to global variable $a. This will destroy local
// variable $a and replace it with a reference to $GLOBALS['a']
global $a

// unset $GLOBALS['a']. Now there is no global variable $a; HOWEVER,
// a reference exists to the original variable container, and so this
// has no effect on our reference to $GLOBALS['a'].
unset( $GLOBALS['a'] )

// create locale variable $a with value 3
$a = 3;

-----------------------

When thinking of references, don't think of the reference being made
directly to the variable itself, think of the reference being made to
the same data container as the variable referenced.

Imagine **X** is an imaginary name of the data container created when a
variable is created.

Let:

    $GLOBALS['a'] = 4;

Which is like:

    $GLOBALS['a'] --> **X** --> 4

Now assign a  reference:

    $b = &$GLOBALS['a'];

Which is like:

    $b --> **X** --> 4

Now unset $GLOBALS['a']:

    unset( $GLOBALS['a'] );

Which is like:

    $GLOBALS['a'] --> UNDEFINED!!

And we still have:

    $b --> **X** --> 4


Hope the helps.

Cheers,
Rob.
-- 
.------------------------------------------------------------.
| InterJinn Application Framework - http://www.interjinn.com |
:------------------------------------------------------------:
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for       |
| creating re-usable components quickly and easily.          |
`------------------------------------------------------------'

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


[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