Drupal 8: Autoloading Basics

Autoloading of PHP classes was introduced in Drupal 7. Through a mechanism known as "the registry", modules were able to specify the files that contained their class definitions, then simply use the classes without needing a require or include statement. This system definitely isn't perfect... Having a database backed registry caused a lot of queries for modules like Views that instantiate a lot of classes. It also required a cache clear to pick up any caches, and forced developers to maintain an explicit list of their classes, which then had to be parsed and scanned each time caches were cleared.

Meanwhile, in the broader PHP world, a system known as PSR-0 was conceived. PSR-0 is able to autoload classes with minimal explicit registration, and has no dependency on the database. Because it is a PHP standard (rather than a Drupal specific standard), you can also count on broad support for your favorite external libraries.

The driving force behind PSR-0 is the namespace declaration, which specifies a unique set of identifiers by which the class is known. Namespaces are a feature introduced in PHP 5.3. Conceptually, they're pretty similar to a phone number. You have different parts split by a separator ('-' for phone numbers, '\' for namespaces), which increase in specificity toward the end. An example of a namespaced class is Drupal\entity\Entity. Let's see how this class breaks down:

Namespace PartWhat is it?
DrupalVendor name
entityModule name
EntityClass Name

The other important part of PSR-0 is that classes must be put in individual files with a .php extension, then placed in directories relative to their namespace. So the class "Drupal\entity\Entity" will actually be found in "/core/modules/entity/lib/Drupal/entity/Entity.php". So now we not only have a longer class name (Drupal\entity\Entity vs Entity in Drupal 7), but we also have a much longer path name as well.

It's not all bad news, though. Once you have your class properly namespaced and placed in it's PSR-0 compliant directory, autoloading is automatic. No more work required. Creating a new "Drupal\entity\Entity" object causes the Symfony autoloader to lookup the autoload root registered for Drupal\entity (which defaults to the entity module's lib/ directory), and resolve the class path from there. No database queries required, and no cache clear is necessary to prime the autoloader.

So to summarize, there are four simple rules to follow for autoloading to work in Drupal 8:

  • 1 class/interface per file
  • The file must be named the same as your class, and end with .php
  • Your module's classes should be namespaced under Drupal\{your module name}
  • Your namespacing needs to match your directory structure, starting from your module's lib/ directory.