Sometimes we will find that a static class method uses a global variable like so:

This is a problem because there is no constructor to which we can move the global variable as a property. There are two options here.

The first option is to pass all the needed globals as parameters on the static method itself, thereby changing the signature of the method:

We would then search the codebase for all uses of Foo::doSomething( and pass the $bar value each time. For that reason, I suggest adding the new parameters to the beginning of the signature, rather than to the end, because it makes search-and-replace much easier. For example:

Search for:

Replace with:

The second option is to change the class so that it must be instantiated, and make all the methods instance methods. The class, after conversion, might look like this:

After that, we would need to:

Superglobals represent a challenging special case when removing global variables. They are automatically global within every scope, so they carry all the drawbacks of globals. We won't find them with a search for the global keyword (although we can search for them by name). Because they truly are global, we need to remove them from our classes just as much as we need to remove the global keyword.

We could pass a copy of each superglobal into the class when we need it. In cases where we need only one this might be fine, but frequently we need two or three or more superglobals. In addition, passing a copy of $_SESSION will not work as expected; PHP uses the actual superglobal of $_SESSION for writing session data, so changes to the copy will not be honored.

As a solution, we can use a Request data structure class. The Request encapsulates a copy of each of the non-$_SESSION superglobals. At the same time, the Request maintains a reference to $_SESSION so that changes to the object property are honored by the real $_SESSION superglobal.

For example, say we have a class that uses $_POST, $_SERVER, and $_SESSION:

To replace these calls, we first create a shared Request object in our setup code.

We can then decouple from the superglobals by injecting that shared Request object in to any class that needs it, and use the Request properties instead of the superglobals: