Middleware

Middleware is a series of layers that incoming HTTP requests must go through before reaching the controllers of your application. This concept is introduced to CodeIgniter by Luthier CI and opens up a range of possibilities in the framework.

Content

Middleware execution points

There are two possible execution points for the Middleware in Luthier CI, and they are related to the loading and execution of CodeIgniter controllers:

  • pre_controller: the Middleware defined at this point will run after the controller's constructor, BUT before any other method is executed.
  • post_controller: the Middleware defined at this point will run exactly on the post_controller CodeIgniter native hook.
The controller constructor always runs first

It is possible that at some point you need to execute code before your Middleware, and the way to do it is by defining a public method in your controller called preMiddleware:

<?php
# application/controllers/TestController.php

defined('BASEPATH') OR exit('No direct script access allowed');

class TestController extends CI_Controller
{
    public function preMiddleware()
    {
        // (...)
    }
}
When you use anonymous functions as controllers there is no way to execute arbitrary code before Middleware

Create a Middleware

All Middleware should be stored in the application/middleware folder. A Middleware is any PHP class that implements the Luthier\MiddlewareInterface interface.

The Luthier\MiddlewareInterface interface only defines a method called run(), which is the entry point of the Middleware.

For example:

<?php
# application/middleware/TestMiddleware.php

class TestMiddleware implements Luthier\MiddlewareInterface
{
    public function run()
    {
        // (...)
    }
}
As of version 0.3.0, the use of Middleware classes that do not implement the Luthier\MiddlewareInterface interface is OBSOLETE and will stop working in the next version

It is necessary that both the class name and the file name are exactly the same.

Avoid using a name of another framework existing resource, such as a controller, model, or library.
A good practice is to add the Middleware suffix to the name of your Middleware.

Assign a Middleware

You can assign a Middleware in different contexts:

Global Middleware

As the name implies, global Middleware runs on all incoming requests from your application:

Route::middleware([name], [exec_point?]);

Where name is the name of the Middleware and exec_point is the execution point (by default, pre_controller)

You can use an anonymous function instead of the name of a middleware:

Route::middleware(function(){
    ci()->load->view('global_header');
});

Middleware in route groups

Route middleware is defined as any other property. In the case of route groups, it goes in the second argument of the Route::group() method:

Route::group('site', ['middleware' => ['AuthMiddleware']], function(){

});

For an individual route, the Middleware is also defined as a property:

Route::put('foo/bar','controller@method', ['middleware' => ['TestMiddleware']]);
In individual routes and route groups, the execution point is ALWAYS pre_controller

Run a middleware programatically

To run a Middleware from a controller, use the run() method of the middleware property:

<?php
# application/controllers/TestController.php

defined('BASEPATH') OR exit('No direct script access allowed');

class TestController extends CI_Controller
{
    public function __construct()
    {
        $this->middleware->run('AuthMiddleware');
    }
}

This method supports a second argument with the parameters of the Middleware:

$this->middleware->run('AuthMiddleware', ['foo' => 'bar']);

It is possible to run Middleware from an external class, as long as it has a run() public method

<?php
# application/controllers/TestController.php

defined('BASEPATH') OR exit('No direct script access allowed');

use Vendor\CustomMiddleware;

class TestController extends CI_Controller
{
    public function __construct()
    {
        $this->middleware->run(new CustomMiddleware());
    }
}