The Trouble with Two Autoloaders

An autoloader is a bit of PHP code designed to load class files as they are needed. This is a language feature of PHP; when an autoloader is registered, PHP will call it any time a reference to an unknown (un-loaded) class is made. Composer makes it even more convenient to use an autoloader, as it will generate one automatically from the information provided in a project’s various composer.json files when the project is installed and updated.

If one autoloader is good, what about using two autoloaders? Composer has been specifically designed to make it possible to include more than one autoload file; in fact, in the early days of Composer, this was the sanctioned way for the unit tests to combine the classes needed for testing with the classes from the application. Unfortunately, unlike belts and suspenders, two PHP autoloaders are not twice as good at holding your pants up. It goes beyond simple redundancy; having multiple autoloaders can actually be actively harmful to your application.

The figure below illustrates how things might go wrong.

Figure: Loading Two Different Copies of the Same Library
Figure: Loading Two Different Copies of the Same Library

In this hypothetical scenario, one program has a library, FancyLib v1.0.1, loaded in its autoload file. If this program then loads a second autoload file that also contains the same library, but at a slightly different version, problems are likely to be encountered. There are a number of ways that things can go wrong; in the example above, a protected function in a base class has been renamed. If a subclass from the second library is loaded and used with the base class from the first library, then a fatal error will be thrown at runtime. The public API for the library has not changed, so Semantic Versioning provides no protection.

Fortunately, it is unusual to encounter a situation where it is tempting to use more than one autoloader. Perhaps the most common example of where two autoloaders are used is when using a global install of Drush or Drupal Console to run commands on a Drupal 8 site. Keeping this working gets a little trickier every time Drupal 8 updates its composer.lock file. At the moment, it is still possible to use the same Drush and Drupal Console with both Drupal 8.0.x and Drupal 8.1.x, but this situation can change with any future release. Stay tuned for future improvements in this area; in the meantime, you might want to consider using a site-local Drush to guard against future problems.

See how Drupal 8 reaches its full potential on Pantheon.

Topics Development, Drupal Planet, Drupal