# Ajout de middleware
# Introduction
Le middleware est basé sur le système défini par le routeur Slim Framework
La déclaration d'un middleware est essentiellement comme celle d'une route.
La propriété priority
est obligatoire. Elle définit l'ordre dans lequel sont enregistrés les middlewares qui ont des
correspondances. Attention, l'ordre d'enregistrement n'est pas forcément l'ordre d'exécution, cela dépend du code du
middleware. Les ordres les plus élevés sont enregistrés en dernier.
La correspondance du pattern est identique à celui d'une route. Pour qu'un middleware soit défini pour un ensemble de
routes, il est possible d'utiliser l'écriture suivante qui indique la correspondance avec toutes les urls qui commence
par /my
.
pattern : "/my[/{args:.*}]"
Pour indiquer un middleware qui corresponde à toutes les routes :
methods : ["ANY"]
pattern : "[/{args:.*}]"
La propriété requiredAccess
n'est pas une propriété du middleware. Le droit d'accès est uniquement pour la route, pas
pour le middleware.
La méthode callable
doit avoir la signature suivante :
Dans le cas, d'une méthode __invoke()
: callable = \My\Routes\Test
(fichier vendor/My/Routes/Test.php
)
public function __invoke(
\Psr\Http\Message\RequestInterface $request,
\Psr\Http\Message\ResponseInterface $response,
callable $next,
array $args
): \Psr\Http\Message\ResponseInterface
À la différence de la route, l'argument $next
est ajouté. Cet argument est la fonction à utiliser pour appeler le
traitement suivant de la réponse. Le traitement suivant est soit le prochain middleware, soit la route effective s'il
n'y a plus de middleware à lancer. L'argument $args
contient les valeurs de la partie variable de pattern.
Exemple : Prétraitement qui ajoute le header "X-Hello: World" à la réponse.
<?php
namespace My\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class HeaderHelloWorld
{
public function __invoke(Request $request, Response $response, callable $next, array $args): Response
{
$response = $response->withHeader("X-Hello", "World");
$response = $next($request, $response);
return $response;
}
}
Exemple : Traitement qui enregistre la durée d'exécution de la route.
namespace My\Middleware;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class LogResponse
{
public function __invoke(Request $request, Response $response, callable $next, array $args): Response
{
$currentRoute = $request->getAttribute("route");
$requestMethod = $request->getMethod();
$mb=microtime(true);
$response = $next($request, $response);
error_log(sprintf("[%s]%s %s [delay : %dms]",
$request->getMethod() ,
$currentRoute->getName(),
$currentRoute->getPattern(),
(microtime(true) - $mb) * 1000
);
return $response;
}
}
# Enregistrement de middleware
L'enregistrement d'un middleware est identique à celui d'une route à la différence du mot-clef "middleware" à utiliser dans le fichier XML.
Exemple : config/MyProject/myMiddles.xml
<sde:config xmlns:router="https://platform.anakeen.com/4/schemas/sde/1.0">
<sde:middlewares namespace="My">
<sde:middleware name="Top">
<sde:priority>100</sde:priority>
<sde:callable>My\Middleware\LogResponse</sde:callable>
<sde:method>ANY</sde:method>
<sde:pattern>[/{args:.*}]</sde:pattern>
<sde:description>Log duration</sde:description>
<sde:requiredAccess/>
</sde:middleware>
<sde:middleware name="Header">
<sde:priority>100</sde:priority>
<sde:callable>My\Middleware\HeaderHelloWorld</sde:callable>
<sde:method>GET</sde:method>
<sde:pattern>/my/hello</sde:pattern>
<sde:description>Add hello header</sde:description>
<sde:requiredAccess/>
</sde:middleware>
</sde:middlewares>
</sde:config>