Skip to content
Rougin Gutib edited this page Aug 10, 2024 · 12 revisions

← Error Handler Component | Routing Component →

Although this is an optional component to Slytherin, the Middleware component is being used through the usage of its interfaces. The main goal of a middleware is to manipulate both the incoming HTTP request and the outgoing HTTP response.

Concept

There is a Medium post that describes the usage of middlewares and its importance in PHP frameworks.

Example Code

To create a middleware, the middleware must be implemented in MiddlewareInterface:

namespace Rougin\Sample;

use Psr\Http\Message\ServerRequestInterface;
use Rougin\Slytherin\Middleware\HandlerInterface;
use Rougin\Slytherin\Middleware\MiddlewareInterface;

class Hello implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, HandlerInterface $handler)
    {
        $response = $handler->handle($request);

        $response->getBody()->write('Hello world!');

        return $response;
    }
}

Note

The example middleware above is currently implemented in Slytherin's own MiddlewareInterface. However, other middlewares that implements on the variants of the PSR-15 standard (http-interop/http-middleware or psr/http-server-middleware) are also supported by converting them back to the built-in MiddlewareInterface of Slytherin.

To use the recently defined middleware, a middleware dispatcher must be used that is implemented to the DispatcherInterface:

// app/web/index.php

use Rougin\Sample\Hello;
use Rougin\Slytherin\Middleware\Dispatcher;
use Rougin\Slytherin\System\Lastone;

// A ServerRequestInterface must be used as its parameter ---
/** @var \Psr\Http\Message\ServerRequestInterface $request */
// ----------------------------------------------------------

$dispatch = new Dispatcher;

// Push the middleware on the end of the "stack"
$dispatch->push(new Hello);

// A final handler must return an empty ResponseInterface ---
$final = new Lastone;
// ----------------------------------------------------------

// Dispatches the defined "stack" using the provided request ---
echo $dispatch->process($request, $final);
// -------------------------------------------------------------

The example code above should return Hello world! after executing the said code in a terminal:

$ php app/web/index.php
"Hello world!"

Using the MiddlewareIntegration

The MiddlewareIntegration is a built-in integration for the Middleware component that can be used for defining only the available middlewares to be added to the Application instance:

 use Rougin\Sample\Hello;
-use Rougin\Slytherin\Middleware\Dispatcher;
-use Rougin\Slytherin\System\Lastone;
+use Rougin\Slytherin\Application;
+use Rougin\Slytherin\Configuration;
+use Rougin\Slytherin\Middleware\MiddlewareIntegration;

 // A ServerRequestInterface must be used as its parameter ---
 /** @var \Psr\Http\Message\ServerRequestInterface $request */
 // ----------------------------------------------------------

-$dispatch = new Dispatcher;
+$config = new Configuration;

 // Push the middleware on the end of the "stack" ---
-$dispatch->push(new Hello);
+$config->set('app.middlewares', array(new Hello));
 // -------------------------------------------------

-// A final handler must return an empty ResponseInterface ---
-$final = new Lastone;
-// ----------------------------------------------------------
-
 // Dispatches the defined "stack" using the provided request ---
-echo $dispatch->process($request, $final);
+$app = new Application(null, $config);
+
+$app->integrate(new MiddlewareIntegration);
+
+echo $app->run();
 // -------------------------------------------------------------

Note

The respective instance that will be created for the said integration is only limited for the third-party packages that are currently supported by Slytherin. The built-in implementation will be used if no third-party packages are installed for the said component.

Third-party implementations

If using the MiddlewareIntegration, Slytherin can integrate the following third-party packages below if their respective packages are installed:

If not using the supported packages above, a list of packages that handles HTTP routing are also listed at the awesome-php repository. Once selected a specified package, it must be implemented in DispatcherInterface:

namespace Rougin\Slytherin\Middleware;

interface DispatcherInterface extends MiddlewareInterface
{
    /**
     * Returns the list of added middlewares.
     *
     * @return \Rougin\Slytherin\Middleware\MiddlewareInterface[]
     */
    public function getStack();

    /**
     * Add a new middleware to the end of the stack.
     *
     * @param  mixed $middleware
     * @return self
     */
    public function push($middleware);

    /**
     * Sets a new stack of middlewares.
     *
     * @param  mixed[] $stack
     * @return self
     */
    public function setStack($stack);
}

← Error Handler Component | Routing Component →