الـ middleware هي واحدة من الإمور التي حصل عليها تغيير بشكل كبير، حيث تم إزالة الملف kernel.php وكذلك المجلد middleware غير موجود.
لإنشاء middleware نستخدم الأمر
php artisan make:middleware BrowserMiddleware INFO Middleware [app/Http/Middleware/BrowserMiddleware.php] created successfully.
بعد تنفيذ الأمر يتم إنشاء المجلد middleware بداخل app/Http وبداخله الـ BrowserMiddleware.
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class BrowserMiddleware { /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { return $next($request); } }
وكما نلاحظ أن structure والدوال الخاصه بالـ middleware لا يختلف عن الإصدارات السابقة.
لكن هذا الـ middleware بحاجة إلى تسجيل، وللقيام بعملية التسجيل، نذهب إلى الملف bootstrap/app.php ونقوم بتسجيله داخل ->withMiddleware مع إستخدام append
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { $middleware->append([ \App\Http\Middleware\BrowserMiddleware::class, ]); }) ->withExceptions(function (Exceptions $exceptions) { // })->create();
كما نلاحظ أنه تم إستخدام append لكن يوجد أيضا prepend
->withMiddleware(function (Middleware $middleware) { $middleware->prepend([ \App\Http\Middleware\BrowserMiddleware::class, ]);
هنا مع إستخدام append و prepend يتم تسجيل middleware بشكل globally إي إننا لسنا بحاجة لإضافته مع route بل يعمل بشكل تلقائي.
أما الفرق بين append و prepend أن append يقوم بتشغيل الـ middleware قبل middleware المعرفة مسبقا في لارافيل، أما prepend فإنه يقوم بتشغيل middleware بعد الـ middlware الموجوده مسبقا في لارافيل.
كما قلنا سابقا، أن لارافيل يأتي بها مجموعة من middlware بشكل إفتراضي وهي
$middleware->use([ // \Illuminate\Http\Middleware\TrustHosts::class, \Illuminate\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Http\Middleware\ValidatePostSize::class, \Illuminate\Foundation\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ]);
وإذا أردنا أن لا تعمل هذه الـ middleware أو تعطيل بعضها مثلا تعطيل TrustHosts::class، هنا نقوم بوضع هذه الكلاسات في الملف bootstrap/app.php مع تعطيل اي كلاس لا نريد أن يعمل
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { $middleware->use([ // \Illuminate\Http\Middleware\TrustHosts::class, \Illuminate\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Http\Middleware\ValidatePostSize::class, \Illuminate\Foundation\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ]); }) ->withExceptions(function (Exceptions $exceptions) { // })->create();
هنا نلاحظ أننا نستخدم use.
في لارافيل 10 بداخل kernel.php نلاحظ أنه كان لدينا $middlewareGroups
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, \ErlandMuchasaj\LaravelGzip\Middleware\GzipEncodeResponse::class, ], 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
في لارافيل 11 يمكن لنا عمل Group Middlware ولكن عن طريق bootstrap/app.php.
اذا كان لدي أكثر من middlware يعملان على نفس route يمكن لنا إستخدام appendToGroup بداخل withMiddleware.
->withMiddleware(function (Middleware $middleware) { $middleware->appendToGroup('browserDetect', [ \App\Http\Middleware\BrowserMiddleware::class, \App\Http\Middleware\Browser2Middleware::class, ]); })
ولإستخدام هذا الـ group على route معين
Route::get('/', function () { return view('welcome'); })->middleware('browserDetect');
نلاحظ عند إستخدام group إننا قمنا بإستخدام الدالة appendToGroup كذلك يمكن لنا إستخدام prependToGroup
والفرق بين appendToGroup و prependToGroup أن لو كان لدي أكثر من group كي أتحكم أي group يعمل قبل الأخر
->withMiddleware(function (Middleware $middleware) { $middleware->appendToGroup('browserDetect', [ \App\Http\Middleware\BrowserMiddleware::class, \App\Http\Middleware\Browser2Middleware::class, ]); $middleware->prependToGroup('browserDetect', [ \App\Http\Middleware\Browser3Middleware::class, ]); })
هنا تستخدم في التعديل على Group معين.
$middleware->remove([ \Illuminate\Session\Middleware\StartSession::class, ]);
use App\Http\Middleware\StartCustomSession; use Illuminate\Session\Middleware\StartSession; $middleware->web(replace: [ StartSession::class => StartCustomSession::class, ]);
لعمل alias لـ middleware معين، هنا نحتاج أيضا للذهاب للملف bootstrap/app.php بداخل withMiddleware نضيف alias
$middleware->alias([ 'browser' => \App\Http\Middleware\BrowserMiddleware::class, ]);
ولإستخدام middleware بإستخدام alias
Route::get('/', function () { return view('welcome'); })->middleware('browser');