Exporting Globals in PHP

I am currently modernizing a legacy PHP application for a client. (The codebase was written earlier this year, in fact; new code can be “legacy” from the outset.) The original developer pulled a dirty trick with global that I had not seen before, and I thought I had seen everything.

Legacy codebases often use global to import a variable into the local scope, usually a global function. For example, they might drag in a database connection:

<?php
// define $db in a config file somewhere
$db = new DatabaseConnection(...);

// this function uses the $db connection via global
function fetch_user_by_id($id)
{
    global $db;
    return $db->fetchAssoc("SELECT * FROM users WHERE id = ?", $id);
}
?>

I see that kind of thing all the time in legacy PHP. However, what I have not seen before is a function exporting a global.

Take a look at the following code. If the $bar variable is not already defined in the global scope, PHP will define it in the global scope for you automatically when you call foo().

<?php
error_reporting(E_ALL);

function foo()
{
    global $bar;
    $bar ++;
}

// $bar is not defined yet, so PHP will show an
// "undefined variable" notice
echo $bar. PHP_EOL;

// calling foo() defines $bar in the global scope,
// and increments it
foo();

// $bar is now available in the global scope, having
// been exported from function foo()
echo $bar. PHP_EOL;

The legacy developer did that because he wanted to keep the variable initialization outside of the global scope for some reason, even though he used the variable in the global scope elsewhere.

It is exceptionally difficult to track down where an exported global is coming from when refactoring a legacy application. If you must write legacy code using globals, initialize them in the global scope. Better yet, don’t use globals at all: pass values as function arguments, or use dependency injection techniques.

Are you stuck with a legacy PHP application? You should buy my book because it gives you a step-by-step guide to improving your codebase, all while keeping it running the whole time.
Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

4 thoughts on “Exporting Globals in PHP

  1. […] I am currently modernizing a legacy PHP application for a client. (The codebase that was written earlier this year, in fact; new code can be “legacy” from the moment it it written.) The original developer pulled a dirty trick with global that I had not seen before, and I …read more […]

  2. Function currency(){
    global $currency;
    $currency = tep_db_query(“select currency_id from currency where language = “.LANGUAGE_EN.”;”);
    }

    // the Db reference is global inside of the tep method. The language_en is not declared anywhere else.

Leave a Reply

Your email address will not be published. Required fields are marked *