Sometimes we will find that a static class method uses a global
variable like so:
The first option is to pass all the needed globals as parameters on the static method itself, thereby changing the signature of the method:
The process described above is a class-by-class process, where we first move the globals in a single class to the constructor, then change from global properties to instance properties in that class, and finally change instantiations of that class.
Alternatively, we might choose a modified process:
Sometimes we will find that classes are instantiated based on variable values. For example, this creates an object based on the value of the $class
variable:
If $type
is Blog
, then the $record
object will be of the class Blog_Record
.
This kind of thing is very difficult to discover when searching for class instantiations to convert to using constructor parameters. I'm afraid I have no good advice for automatically finding these kinds of instantiations. The best we can do is to search for new\s+\$
without any class name, and modify the calls individually by hand.
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.
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:
There is one more superglobal that PHP provides: $GLOBALS
. Using this superglobal inside our classes and methods should be treated as a use of the global
keyword. For example, $GLOBALS['foo']
is the equivalent of global $foo
. We should remove it from our classes in just the same way as we do with uses of global
.