[development] Beware of static and unset together

Karoly Negyesi karoly at negyesi.net
Fri Apr 6 07:45:09 UTC 2007


Hi,

So says the PHP manual about unset

"If a static variable is unset() inside of a function, unset() destroys  
the variable only in the context of the rest of a function. Following  
calls will restore the previous value of a variable."

This will lead to really weirdo stuff if you have:

function foo($refresh = FALSE) {
   static $storage;
   if ($refresh) {
     echo "refreshing\n";
     unset($storage);
   }

   if (!isset($storage)) {
     $storage = microtime();
   }
   return $storage;
}
echo foo() ."\n";
echo foo(TRUE) ."\n";
echo foo() ."\n";

Observe how the third and the first results are the same as if the refresh  
did not happen.

As Drupal often uses such constructs. Use $storage = NULL instead of  
unset, for example -- or some other appropriate initial value like '' or  
array(). list_themes() in core for example has been biten by this, thanks  
goes to dww for reporting it. The patch is at  
http://drupal.org/node/134161 btw.

I think it's better known that if you have global $x; unset $x; then $x  
will be unset only in local scope, as global $x is same as saying $x =  
&GLOBALS['x']; The above issue is actually the same because -- according  
to my knowledge -- static is a global which has a special flag 'you are  
only visible to function foo', so basically you have $storage =  
&$GLOBALS['_static']['foo']['storage']; and then you destroy this  
reference (of course GLOBALS['_static'] does not exist, I just used it for  
illustration).

Regards,

NK


More information about the development mailing list