Overview of Symfony Components in Drupal 8

Overview of Symfony Components in Drupal 8 image

When the decision was made to build Drupal 8 on Object-Oriented Programming (OOP) principles, the job was made easier because of the existence of open-source reusable PHP libraries from the Symfony project. The following components were selected for use (in addition to the standalone Twig template engine).

ClassLoader

This component is a solution to the challenge of automatically loading classes in a PHP project. Due to the nature of the language and the diverse communities of developers, there can be hundreds or thousands of files from different vendors. The files need to be made available by including or requiring them at different places in the scripts that make up an application. Newer versions of PHP allow you to define how to load files automatically.

This component defines three ways of doing this provided you follow the recommended ways of structuring your code. PSR-0 Class Loader (for files named according to PSR-0 standards), PSR-4 Class Loader (for files named according to PSR-4 standards), and MapClassLoader (from an array of full paths to files, each keyed by a string alias).

Example: In index.php an autoloader is required to ease access to classes in the application.

$autoloader = require_once 'autoload.php';

Console

This component allows the building of Command Line Interface (CLI) tools that give interactive access to an application.

Drupal Console is an excellent example. Site administrative tasks such as running cron jobs, managing user accounts, taking sites offline and back online can be performed from the command line. Developer experience is improved by boilerplate code generation or creation of dummy content in a development environment.

CssSelector

Most PHP developers have heard about CSS selectors and probably worked with them. However, not all of them would have worked with XML Path Language (XPath) as extensively as CSS. When parsing structured documents XPath expressions are more powerful than CSS selectors.

The CssSelector Component bridges this gap by converting CSS selectors to XPath expressions which can then be used in relevant situations, e.g., when searching for an element in an HTML document.

Example: To get the link title in a Views row in a unit test:

$row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))->getText();

DependencyInjection

In a large application, there may be hundreds or thousands of objects to initialize either with or without dependencies. And the dependencies may have other dependencies which need to be instantiated first.

The DependencyInjection Component manages the construction of all objects in a centralized and standardized way. Before creating an instance of an object, all its dependencies are initialized and passed to it. What this means is that an object can not be instantiated without all its dependencies being met.

In other to do this effectively, there is a Service Container which is a single object that holds all other objects, called services, that are present in an application. Each service is identified by a Service ID, something that is like an associative array key, by which the service is identified. The container provides an interface for fetching services when required.

EventDispatcher

The EventDispatcher coordinates how components of an application communicate with each other. This is done by defining events which are announced, broadcast, or dispatched when they occur. Other parts of the system, called listeners, that have subscribed to these events listen for them. When an event is dispatched, each listener then carries out actions which they registered with the component.

HttpFoundation

The HTTP specification describes how data is communicated across the internet based on a request-response exchange. These variables come from different sources and are not always represented consistently.

The HttpFoundation Component abstracts these global variables that represent a request into a PHP object. In addition, this object also encapsulates the process of generating responses. A simple interface to request variables and response functions is provided by this component.

HttpKernel

The HTTP specification defines a request/response protocol. A client, such as a web browser, sends a request to the server and the server returns a response, which may be a web page if the client is a browser. Different systems and applications have different ways of handling this process of taking a request and replying with a response.

The HttpKernel Component is the way Symfony solves the problem of conversion of Request into Response by working in conjunction with the EventDispatcher Component.

Example: index.php summarises the usage of these major components:

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

// get autoloader
$kernel = new DrupalKernel('prod', $autoloader);

$request = Request::createFromGlobals();
$response = $kernel->handle($request);
//

PHPUnit Bridge

This component extends PHPUnit tests by offering insight into deprecated features that are still in use by an application.

This is very useful in an application such as Drupal that has been transformed with each major version. And in the latest version, it aims to achieve an increased level of code coverage as developers are encouraged to write more and more unit tests.

Polyfill Iconv

The iconv PHP module provides the functionality of conversion of text from one character set encoding to the other. This is very important in the internet age as the same text may be presented to different audiences in different language contexts which often require different encodings.

This component is an OOP abstraction of iconv_* functions of the PHP iconv module.

Process

PHP allows the execution of system commands, but their behavior may be different on different operating systems. This component abstracts the proc_* part of program execution functions in an Object-Oriented Programming (OOP) way, enabling the uniform execution of separate sub-processes.

Routing

HTTP deals with requests for resources on a server. The name or location of the resource is identified by the Uniform Resource Identifier (URI). Also, a Uniform Resource Locator (URL) describes how to locate the resource and how to access it.

The Routing Component maps URLs to controllers that retrieve the requested resource as a response.

Example: This is the routing configuration file for the profile page for a logged in user:

# core/modules/user/user.routing.yml

user.page:
  path: '/user'
  defaults:
    _controller: '\Drupal\user\Controller\UserController::userPage'
    _title: 'My account'
  requirements:
    _user_is_logged_in: 'TRUE'

Serializer

Data serialization is the complex process of transforming objects into a different format, e.g., JSON, XML, YAML, etc. This also includes the reverse process of deserialization.

Usually, there is an intermediate step of having arrays between objects and formats with Encoders working on formats and Normalizers on objects.

Translation

These days, multilingual websites are the norm rather than an exception. The Symfony project has built tools for the management of translations and made them available in the Translation Component.

Validator

Data validation is required in different situations across web applications. This component implements industry standards and specifications for validation in PHP based upon Constraints (validation rules) and Validators (validation logic).

Yaml

YAML Ain't Markup Language (YAML) is a data serialization language. It is very easy to read for humans which makes it useful for configuration files. The YAML Component can parse YAML files into PHP arrays and dump arrays into YAML strings.

Example: This is the info file for the node module.

# core/modules/node/node.info.yml

name: Node
type: module
description: 'Allows content to be submitted to the site and displayed on pages.'
package: Core
configure: entity.node_type.collection
dependencies:
  - text

Conclusion

Drupal has selected some Symfony components to meet specific needs. Other PHP projects such as Laravel, Silex, Pimcore, Sylius, Joomla!, etc. selected different sets of components which met their requirements to build upon, their way. This means there is a cross-pollination of ideas across projects and a less-steep learning curve when working with new technologies.

I hope that this brief overview has sufficiently covered the foundation of Drupal 8 for you to look forward with excitement to learning more.

KEEP MOVING FORWARD

Deji Akala / drupal