Drupal and PSR-4

Objectives
  • Learn about how the PSR-4 standard helps interoperability between different libraries.
  • Discover how, following PSR-4, namespaces are related to directory names.
  • Re-examine the code we've created so far and identify where and how namespaces were used.
  • Learn about fully qualified namespaces, and how to import namespaces.

PSR-4: an interop and autoloading standard

PSR-4 stands for PHP Standard Recommendation 4. It's the 4th standard set by the PHP Framework Interop Group

PSR-4 describes how code classes can be "autoloaded" if they use a certain naming convention and directory structure.

Autoloading is an important concept: it's a mechanism that lets applications figure out for themselves which classes from which libraries need to be loaded in memory at any given time.

Without autoloading you would have to include() or require() library files manually, which can become a maintenance nightmare.

The other option is what previous Drupal versions did: load all of the classes in memory all the time, which resulted in Drupal using much more memory than really needed on each page load.

For Drupal 8, 9 and 10 the rules are:

  • Each class should be declared in its own file.
  • All classes should be declared to be in a namespace.
  • The namespace should start with Drupal\name-of-the-module
  • Each class file goes into a specific directory/subdirectory, depending on its namespace.

Let's revisit the my_route_demo example:

Directory structure:

Code
/modules/custom/my_route_demo
├── src
│    └── Controller
│           └── HelloController.php
├── my_route_demo.routing.yml
└── my_route_demo.info.yml

Controller code (partial):

Code
namespace Drupal\my_route_demo\Controller;

// [...]

class HelloController extends ControllerBase {
   // [...]
}

Compare the location of the controller class

my_route_demo/src/Controller/HelloController.php

with the namespace

Drupal\my_route_demo\Controller

You'll notice both are similar, but not identical. 

For your convenience, Drupal module namespaces are automatically mapped to each module's /src/ directory.

Other examples you may encounter:

  • Drupal\mymodule\Plugin\Block\WelcomeBlock is mapped to mymodule/src/Plugin/Block/WelcomeBlock.php.
  • Drupal\mymodule\Form\SignupForm is mapped to mymodule/src/Form/SignupForm.php.

Important to remember

The important, practical things to remember at this point are:

  • You MUST provide a valid namespace for every class you write as part of a Drupal module.
  • Pay very close attention to the namespace and directory structure when recreating the example code.
  • Be aware that component types (routes, forms, plugins, blocks, ...) each have their own specific folder structure and matching namespace. Deviating from this structure will result in broken code, ranging from explicit error messages to your components silently failing.

Throughout this course we will come back to these conventions and point out when to pay special attention to them.