К примеру, существует посредник для проверки авторизации пользователя. Если пользователь неавторизован, то посредник переадресует его на страницу авторизации. Иначе позволит продолжить работу.
Все посредники в Laravel расположены в каталоге
app/Http/Middleware
.
Создание посредника
Для создания посрденика используется команда Artisan "make:middleware". Попробуем сделать посредника под названием CheckValue:php artisan make:middleware CheckValue
В резулдьтате выполнения этой команды будет создан класс CheckValue в каталоге посредников. Теперь необходимо написать в нём обработчик. Предположим, что посредник CheckValue будет проверять действительно ли значение числа больше 50. Иначе буде будет происходить переадресация на домашнюю страницу сайата:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckValue{
public function handle($request, Closure $next){
if ($request->value <= 50) {
return redirect('home');
}
return $next($request);
}
}
?>
Если нужно запускать посредник для каждого HTTP запроса, то нужно добавить посредник в свойство "$middleware" класса
app/Http/Kernel.php
.Назначение посредника для маршрутов
Если нужно добавить вызов посредников для конкретных маршрутов, то сначала надо добавить ключ посредника в класс app/Http/Kernel.php. В это классе свойство "$routeMiddleware" содержит всех посредников системы. В классе уже имеются свои посредники, добавьте к ним свой (ключ можно написать любой). Например:<?php
// в классе app/Http/Kernel
protected $routeMiddleware = [
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
];
?>
После определения посредника в ядре можно использовать его в маршруте с помощью метода middleware. В качестве параметров ему передаётся один или несколько названий посредников:
<?php
Route::get('admin/profile', function () {
// ... маршрут
})->middleware('auth', 'guest');
?>
Помимо названий посредников можно использовать полное имя класса:
<?php
Route::get('admin/profile', function () {
// ... маршрут
})->middleware(CheckValue::class);
?>
Для сокрашения записи можно использовать массив в параметре маршрута. Перепишем предыдуший пример:
<?php
Route::get('/', ['middleware' => ['auth', 'guest'], function () {
// ... маршрут
}]);
?>
Если посредников слишком много, то стоит организовать их в группу при помощи "$middlewareGroups" из HTTP-ядра. Посредники в группах будут выполняться все последовательно, так их проще назначать на маршруты. Группы можно создать по аналогии с уже существующими, в Laravel есть группы посредников web и api:
<?php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'auth:api',
],
];
?>
Для назначения групп посредников достаточно передать их название группы в параметр метода middleware:
<?php
Route::get('admin/profile', function () {
// ... маршрут
})->middleware('web');
?>
Параметры посредников
Посредникам можно передавать дополнительные параметры. Попробуем переписать пример из начала статьи, передав параметром значение "50", которое использовали для сравнения в CheckValue. Такие параметры будут передаваться в посредник после аргумента $next. Обзовём параметр "maxVal":<?php
namespace App\Http\Middleware;
use Closure;
class CheckValue{
public function handle($request, Closure $next, $maxVal){
if ($request->value <= $maxVal) {
return redirect('home');
}
return $next($request);
}
}
?>
Теперь чтобы передать значение $maxVal из маршрута в посредник, необходимо написать в параметре к методу "middleware". Причём запись должна быть через двоеточие, сначала название посредника, а потом параметр:
<?php
Route::get('admin/profile', function () {
// ... маршрут
})->middleware('CheckValue:15');
?>
Таким образом в переменную $maxVal попадёт значение "15".
Исполнение посредника после HTTP отклика
Иногда нужно выполнять часть действий посредника только после отправки HTTP отклика клиенту. Для этого в посреднике необходимо определить метод с названием "terminate". Он будет автоматическе вызываться только после отправки отклика. К примеру, такой метод уже есть в стандартном посреднике Laravel поод названием "session":<?php
namespace Illuminate\Session\Middleware;
use Closure;
class StartSession{
public function handle($request, Closure $next) {
return $next($request);
}
public function terminate($request, $response) {
// действие после отправки HTTP отклика
}
}
?>
Обратите внимание, что такой посредник обязательно должен быть добавлен в список глобальных посредников в HTTP ядре.