A free and open-source book on ZF3 for beginners

4.11. Controller Plugins

A controller plugin is a class which extends the functionality of all controllers in some way.

Without plugins, to extend the functionality of all controllers, you would have to create a custom base class, say BaseController, and derive other controllers from that base class. This way can also be used, but from ZF3 creators' point of view, plugins are better solution, because they use class composition 2, which provides better flexibility comparing to class inheritance. You register your plugin controller and it automatically becomes accessible from all controllers of your app (AbstractActionController base class uses PHP's __call() magic method to proxy calls to registered controller plugins).

2) Composition is a relationship between two classes that is best described as a "has-a" and "whole/part" relationship. The owner class contains a reference to another class (plugin). The owner is responsible for the lifetime of the object it holds.

There are several standard controller plugins available out of the box (table 4.6), and we've already used one of them (the Params plugin) in one of our previous examples.

Table 4.6. Standard Controller Plugins
Standard Plugin Class Description
Params Allows to retrieve variables from HTTP request, including GET and POST variables.
Url Allows to generate absolute or relative URLs from inside controllers.
Layout Gives access to layout view model for passing data to layout template.
Identity Returns the identity of the user who has logged into the website.
FlashMessenger Allows to define "flash" messages which are stored in session and can be displayed on a different web page.
Redirect Allows to redirect the request to another controller's action method.
PostRedirectGet Redirects the POST request, converting all POST variables to GET ones.
FilePostRedirectGet Redirects the POST request, preserving uploaded files.

Inside of the controller's action method, you access a plugin in the following way:

// Access Url plugin
$urlPlugin = $this->url();

// Access Layout plugin
$layoutPlugin = $this->layout();

// Access Redirect plugin
$redirectPlugin = $this->redirect();

As an alternative, you can invoke a plugin by its fully qualified name with the plugin() method provided by the base controller class, as follows:

use Zend\Mvc\Controller\Plugin\Url; 
// Inside your controller's action use the plugin() method.
$urlPlugin = $this->plugin(Url::class);

4.11.1. Writing Own Controller Plugin

In your websites, you will likely need to create custom controller plugins. For example, assume you need that all your controller classes to be able to check whether a site user is allowed to access certain controller action. This can be implemented with the AccessPlugin class.

The controller plugin should be derived from the AbstractPlugin class. Plugins typically live in their own namespace Plugin, which is nested in Controller namespace:

namespace Application\Controller\Plugin; 

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

// Plugin class
class AccessPlugin extends AbstractPlugin 
    // This method checks whether user is allowed
    // to visit the page 
    public function checkAccess($actionName)
        // ...

To let Zend Framework 3 know about your plugin, you need to register it in your module.config.php file under the controller_plugins key. See below for example:

return [
    // ... 
    'controller_plugins' => [
        'factories' => [
            Controller\Plugin\AccessPlugin::class => InvokableFactory::class,
        'aliases' => [
            'access' => Controller\Plugin\AccessPlugin::class,
    // ...

Please note that we also register an alias for the plugin to be able to get the plugin by its short name.

After that, you'll be able to access your custom plugin from all of your controller's actions in this way:

// Check if site user is allowed to visit the "index" page
$isAllowed = $this->access()->checkAccess('index');