Are global variables in PHP considered bad practice? If so, why?

Reposted from the ended SO Documentation Beta

We can illustrate this problem with the following pseudo-code

function foo() {
     global $bob;
     $bob->doSomething();
}

Your first question here is an obvious one

Where did $bob come from?

Are you confused? Good. You’ve just learned why globals are confusing and considered a bad practice. If this were a real program, your next bit of fun is to go track down all instances of $bob and hope you find the right one (this gets worse if $bob is used everywhere). Worse, if someone else goes and defines $bob (or you forgot and reused that variable) your code can break (in the above code example, having the wrong object, or no object at all, would cause a fatal error). Since virtually all PHP programs make use of code like include('file.php'); your job maintaining code like this becomes exponentially harder the more files you add.

How do we avoid Globals?

The best way to avoid globals is a philosophy called Dependency Injection. This is where we pass the tools we need into the function or class.

function foo(\Bar $bob) {
    $bob->doSomething();
}

This is much easier to understand and maintain. There’s no guessing where $bob was set up because the caller is responsible for knowing that (it’s passing us what we need to know). Better still, we can use type declarations to restrict what’s being passed. So we know that $bob is either an instance of the Bar class, or an instance of a child of Bar, meaning we know we can use the methods of that class. Combined with a standard autoloader (available since PHP 5.3), we can now go track down where Bar is defined. PHP 7.0 or later includes expanded type declarations, where you can also use scalar types (like int or string).

Leave a Comment