We are introduced to the concept of autoloading near the top of the index.php
file of Drupal 8:
$autoloader = require_once 'autoload.php';
Autoloading is a unified way of including files anywhere in an application while ensuring they are found at a specified location. It boils down to a method or function that generates require
statements for as many files as determined by the code.
In the early days of PHP applications, as scripts grew in size, it became common practice to include a file in others either for file size management or code reuse. Understandably, there is no limit to the number of includes and they can come anywhere in a file but often at the very top.
PHP applications grew in complexity, and each version introduced new features. The ones that drew the most attention were in Object-Oriented Programming (OOP), which modern programming languages touted. The basic premise was seeing the abstract world of bytes in the light of a physical world of objects with properties and behaviors. Coding in this way added classes to the existing concepts of variables, statements, functions (or methods). A simple application may have hundreds of files or classes. Autoloading is an effective way of managing them.
So getting an instance of the autoloader stored in $autoloader
very early in the application life-cycle is perfect. The PHP parser looks for the autoload.php
file in the same directory as index.php
and includes it.
Let us see the magic inside the included file:
// autoload.php
return require __DIR__ . '/vendor/autoload.php';
Another require
statement? Another autoload.php
? The difference here is that the statement is require
unlike require_once
in index.php
. And more importantly, something is returned and whatever is returned is stored in the $autoloader
variable we saw earlier in index.php
.
This second autoload file is important because the vendor
folder might be in a different location. The file is quite similar to the first one.
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitDrupal8::getLoader();
Initially, this might look confusing, but we shall see the reasoning behind this in a second. With this final require
statement we end up with a ComposerAutoloaderInitDrupal8
class, which is defined in vendor/composer/autoload_real.php
, and call its getLoader()
method.
When Composer has downloaded the dependencies for a site, it generates some autoload classes with arrays of namespaces and class maps under vendor/composer
. Inside the same folder as autoload_real.php
we also have autoload_classmap.php
, autoload_files.php
, autoload_namespaces.php
, autoload_psr4.php
, and autoload_static.php
. These are different ways of identifying the location of classes available in the packages under the vendor
folder.
In the getLoader()
method, depending on whether a static loader is to be used or not, the right autoload classes are included, and the \Composer\Autoload\ClassLoader
instance is properly initialized.
The returned object is passed on to the second require
statement, which in turn gets passed on to the line in our index.php
file and assigned to a variable - $autoloader
.
Adding some entries to settings.php
file allows you to have a finer level of control over the class-loading process. If the APC extension for PHP is available on the server, the Symfony APC class loader is used for improved performance. If you do not want this detection, make sure this is in your settings.php
. It should already be there in a commented line - just uncomment it:
$settings['class_loader_auto_detect'] = FALSE;
Even without the APC extension, you can still benefit from Symfony's APC class loader by decorating and replacing the local $class_loader
variable. Uncomment the following lines in settings.php
and see the comment above the code block for further details about it:
if ($settings['hash_salt']) {
$prefix = 'drupal.' . hash('sha256', 'drupal.' . $settings['hash_salt']);
$apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $class_loader);
unset($prefix);
$class_loader->unregister();
$apc_loader->register();
$class_loader = $apc_loader;
}
Modern PHP web applications may pull a large number of packages and libraries from different sources. They manage package dependencies with Composer which provides a central way of finding classes and making them available throughout an application. Drupal 8 is an excellent exponent of autoloading which plays a key role in the journey of an HTTP request from the moment it arrives at the front controller, the index.php
file.