The unsettling Truth about the Global Unset

In PHP, there is a pitfall when using unset on a global variable within the scope of a function or method. When referred to using the global keyword within a function, unset will not destroy the global variable within the global scope.

global $banana;
$banana = 'yellow';
function monkey() {
    global $banana;
    unset( $banana );
}
monkey();
echo $banana;

The output produced (1) by the code above is not a warning, but:

yellow

Although one might expect otherwise, the unset in the function only has an effect on the local reference to the global variable. The unset has an effect within the scope of the function, but not outside of it, meaning that the global variable will retain its value.

To use unset to really destroy the global variable in the global scope, we have to use the $GLOBALS superglobal instead:

global $banana;
$banana = 'yellow';
function ape() {
    unset( $GLOBALS['banana'] );
}
ape();
echo $banana;

This time, the unset truly has the effect of destroying the global variable within the global scope. The output produced by the above code is:

Warning: Undefined variable $banana in php shell code on line 1

Call Stack:
   15.7511     394600   1. {main}() php shell code:0

If you are not aware of this, you might find yourself trying to figure out weird side-effects in code that looks obviously correct, but isn’t.

A Real-World Case Example

Science does not care about your beliefs … Computer Science is particularly nihilistic.

It doesn’t matter how experienced I am, when my assumptions are wrong.

I came to figure this particular case out after hours of head-scratching and refactoring, when the light dawned on me during a debugging session – which revealed that the value of an important global variable was left untouched in the global scope after trying to use unset on it.

In the free WooCommerce Coupon Shortcodes extension, we use the global variable $woocommerce_coupon_shortcodes_codes to provide context across the shortcodes handled by the extension.

Depending on the shortcode, it is necessary to reset or clear the value of this global variable, so that the wrong context is not assumed when another shortcode instance relies on its value. On this particular line of code in the currently latest release, the approach of using $GLOBALS to destroy the value of the global variable is used:

unset( $GLOBALS['woocommerce_coupon_shortcodes_codes'] ); // OK!

As you can imagine, the innocent attempt of using unset on the global variable instead was utterly futile:

unset( $woocommerce_coupon_shortcodes_codes ); // NO!

Have you had a similar experience or any questions related to this? Comment below!


(1) You can easily verify the examples by entering PHP’s Interactive Shell from the command line:
$ php -a


Featured Image derived from a Photo by James Hammond on Unsplash

, , , , , , , , , , , , , ,

No comments yet.

Leave a Reply

We use cookies to optimize your experience on our site and assume you're OK with that if you stay.
OK, hide this message.

Affiliates · Contact · Jobs · Terms & Conditions · Privacy Policy · Documentation · Downloads · Useful Plugins · My Account

Share