Appending & prepending middlewares

Appending & prepending middlewares

2024-10-12 وقت القراءه : 3 دقائق

الـ middleware هي واحدة من الإمور التي حصل عليها تغيير بشكل كبير، حيث تم إزالة الملف kernel.php وكذلك المجلد middleware غير موجود.


كيفية إنشاء middleware في Laravel 11

لإنشاء 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 بشكل يدوي ( لا تعمل على جميع التطبيق ).

كما قلنا سابقا، أن لارافيل يأتي بها مجموعة من 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.


الـ Middleware Groups في Laravel 11

في لارافيل 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 معين.


إزالة middlware من web او api

$middleware->remove([
    \Illuminate\Session\Middleware\StartSession::class,
]);


إستبدال middleware

use App\Http\Middleware\StartCustomSession;
use Illuminate\Session\Middleware\StartSession;
 
$middleware->web(replace: [
    StartSession::class => StartCustomSession::class,
]);


Middleware alias  في Laravel 11

لعمل 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');
إضافة تعليق
Loading...