Вы можете запускать код до и после вашего Slim-приложения, чтобы управлять объектами Request and Response по своему усмотрению. Это называется middleware (промежуточным программным обеспечением). Зачем вам это делать? Возможно, вы хотите защитить свое приложение от подделки межсайтовых запросов. Возможно, вы хотите аутентифицировать запросы перед запуском приложения. Middleware идеально подходит для этих сценариев.
Технически говоря, middleware является вызываемым которое принимает три аргумента:
\Psr\Http\Message\ServerRequestInterface
- Объект запроса PSR7\Psr\Http\Message\ResponseInterface
- Объект ответа PSR7callable
- Следующее middleware (промежуточное программное обеспечение), подлежащее вызовуОн может делать все, что подходит этим объектам. Единственное жесткое требование заключается в том, что промежуточное
ПО ДОЛЖНО возвращать экземпляр \Psr\Http\Message\ResponseInterface
.
Каждое промежуточное ПО СЛЕДУЕТ вызывать следующее промежуточное программное обеспечение и передавать его
объектам Request and Response в качестве аргументов.
Различные структуры используют промежуточное ПО по-разному. Slim добавляет промежуточное ПО как концентрические слои, окружающие ваше основное приложение. Каждый новый слой промежуточного программного обеспечения окружает любые существующие уровни промежуточного программного обеспечения. Концентрическая структура расширяется наружу, когда добавляются дополнительные слои промежуточного слоя.
Последний добавленный слой промежуточного программного обеспечения является первым, который будет выполнен.
Когда вы запускаете приложение Slim, объекты Request and Response пересекают структуру промежуточного программного обеспечения извне. Сначала они вводят самое внешнее промежуточное ПО, а затем следующее внешнее самое промежуточное ПО (и т. Д.), пока они в конечном итоге не прибудут к самому Slim-приложению. После того, как приложение Slim отправляет соответствующий маршрут, результирующий объект Response выходит из приложения Slim и пересекает структуру промежуточного программного обеспечения изнутри. В конечном итоге конечный объект Response выходит из самого промежуточного ПО, сериализуется в исходный HTTP-ответ и возвращается клиенту HTTP. Вот диаграмма, иллюстрирующая поток процесса промежуточного программного обеспечения:
Middleware является вызываемым, которое принимает три аргумента: объект Request, объект Response и следующее middleware.
Каждое middleware ДОЛЖНО возвращать экземпляр \Psr\Http\Message\ResponseInterface
.
Пример middleware замыкания.
<?php
/**
* Example middleware closure
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
};
Это пример middleware вызываемого класс о который реализует магический метод __invoke()
.
<?php
class ExampleMiddleware
{
/**
* Example middleware invokable class
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function __invoke($request, $response, $next)
{
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
}
}
Чтобы использовать этот класс в качестве middleware, вы можете использовать ->add( new ExampleMiddleware() );
цепочку функций после $app
, Route
, или group()
, что в приведенном ниже коде, любой из них, может
представлять объект $ subject.
$subject->add( new ExampleMiddleware() );
Вы можете добавить промежуточное программное обеспечение в Slim-приложение, на индивидуальный маршрут Slim или в группу маршрутов. Все сценарии принимают одно и то же middleware и реализуют один и тот же интерфейс middleware.
Для каждого входящего HTTP-запроса вызывается middleware. Добавьте промежуточное программное обеспечение
приложения с помощью add()
метода экземпляра Slim. В этом примере добавляется пример Closure middleware:
<?php
$app = new \Slim\App();
$app->add(function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
});
$app->get('/', function ($request, $response, $args) {
$response->getBody()->write(' Hello ');
return $response;
});
$app->run();
Это вывело бы это тело ответа HTTP:
BEFORE Hello AFTER
Route middleware вызывается только в том случае, если его маршрут соответствует текущему методу HTTP-запроса и URI.
Route middleware указывается сразу же после вызова любого из методов маршрутизации Slim-приложения
(например get()
или post()
). Каждый метод маршрутизации возвращает экземпляр \Slim\Route
,
и этот класс предоставляет тот же интерфейс middleware что и экземпляр приложения Slim. Добавьте middleware в
маршрут с помощью add()
метода экземпляра Route. В этом примере добавляется пример Closure middleware:
<?php
$app = new \Slim\App();
$mw = function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
};
$app->get('/', function ($request, $response, $args) {
$response->getBody()->write(' Hello ');
return $response;
})->add($mw);
$app->run();
Это вывело бы это тело ответа HTTP:
BEFORE Hello AFTER
В дополнение к общему приложению и стандартным маршрутам, способным принимать middleware, group()
функция определения нескольких маршрутов, также позволяет индивидуальные маршруты внутри.
Маршрутное групповое middleware вызывается только в том случае, если его маршрут соответствует одному из
определенных методов HTTP-запроса и URI из группы. Чтобы добавить промежуточное программное обеспечение в обратном
вызове и промежуточное ПО всей группы, можно установить путем цепочки add()
после group()
метода.
Пример приложения, используя callback middleware в группе обработчиков URL-адресов
<?php
require_once __DIR__.'/vendor/autoload.php';
$app = new \Slim\App();
$app->get('/', function ($request, $response) {
return $response->getBody()->write('Hello World');
});
$app->group('/utils', function () use ($app) {
$app->get('/date', function ($request, $response) {
return $response->getBody()->write(date('Y-m-d H:i:s'));
});
$app->get('/time', function ($request, $response) {
return $response->getBody()->write(time());
});
})->add(function ($request, $response, $next) {
$response->getBody()->write('It is now ');
$response = $next($request, $response);
$response->getBody()->write('. Enjoy!');
return $response;
});
При вызове /utils/date
метода будет выводиться строка, подобная приведенной ниже
It is now 2015-07-06 03:11:01. Enjoy!
посещение /utils/time
будет выводить строку, подобную приведенной ниже
It is now 1436148762. Enjoy!
но посещение /
(domain-root), должно было бы генерировать следующий результат, поскольку не было назначено middleware
Hello World
Самый простой способ передать атрибуты из промежуточного программного обеспечения - использовать атрибуты запроса.
Установка переменной в middleware:
$request = $request->withAttribute('foo', 'bar');
Получение переменной в обратном вызове маршрута:
$foo = $request->getAttribute('foo');