phplaravelcontrollerlaravel-middlewarelaravel-11

Laravel 11 - HasMiddleware's middleware() method conflits with Illuminate\Routing\Controller's middlware()


In my Controller that extends the Illuminate\Routing\Controller, i am trying to implement some middlware validations using the new HasMiddleware.

This is the code that i am trying to run:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;

class BaseController extends Controller implements HasMiddleware
{
    public static $readPermission = null;

    public static $customPermissionChecks = [];

    public static function middleware(): array
    {
        return array_merge([
            'auth:api',
            new Middleware('permission:' . self::$readPermission, ['only' => ['index', 'show']]),
            new Middleware('permission:write.' . self::$readPermission, ['only' => ['edit', 'store', 'update', 'destroy', 'restore']])
        ], self::$customPermissionChecks);
    }
}

However Illuminate\Routing\Controller's middlware() is confliting with the HasMiddleware's static method giving me the following error:

Cannot make non static method Illuminate\Routing\Controller::middleware() static in class App\Http\Controllers\BaseController


Solution

  • You are extending the wrong Controller class

    use the base controller in App\Http

    use App\Http\Controllers\Controller;
    
    class BaseController extends Controller
    

    Instead of the one you used

    use Illuminate\Routing\Controller;
    
    class BaseController extends Controller
    

    The one in Illuminate\Routing contains a method middleware() that is not static so you cant change its type

    /**
     * Register middleware on the controller.
     *
     * @param  \Closure|array|string  $middleware
     * @param  array  $options
     * @return \Illuminate\Routing\ControllerMiddlewareOptions
     */
    public function middleware($middleware, array $options = [])
    {
        foreach ((array) $middleware as $m) {
            $this->middleware[] = [
                'middleware' => $m,
                'options' => &$options,
            ];
        }
    
        return new ControllerMiddlewareOptions($options);
    }