路由和控制器中的中间件

时间:2017-09-27 20:27:18

标签: php laravel laravel-5

我试图在特定路由以及控制器构造函数内部运行中间件。

但是,似乎没有为包含中间件的路由执行在控制器构造函数内定义的中间件。

这不可能吗? (所有这些中间件都在kernel.php中注册,构造函数中的所有中间件在添加中间件到路由之前都在工作)

路线

Route::get('/{organization_slug}', function($organization_slug){

    $organization = \App\Organization::where('slug', '=', $organization_slug)->first();

    $app = app();
    $controller = $app->make('\App\Http\Controllers\OrganizationController');
    return $controller->callAction('details', $parameters = array($organization->id));

})->middleware('verifyorganizationslug');

控制器构造函数

    public function __construct()
    {
        $this->middleware('auth', ['only' => ['create', 'update', 'store']]);
        $this->middleware('accountactive', ['only' => ['create', 'update', 'store']]);
        $this->middleware('ownsorganization', ['only' => ['update']]);
        $this->middleware('verifyorganization', ['only' => ['details']]);

    }

1 个答案:

答案 0 :(得分:0)

gatherMiddleware中,在将路由中间件与控制器中间件合并后,选择了独特的中间件。

public function gatherMiddleware()
{
    if (! is_null($this->computedMiddleware)) {
        return $this->computedMiddleware;
    }
    $this->computedMiddleware = [];
    return $this->computedMiddleware = array_unique(array_merge(
        $this->middleware(), $this->controllerMiddleware()
    ), SORT_REGULAR);
}

如果您正在查看映射到details方法的操作,则应该会看到verifyorganizationslug然后verifyorganization已应用。

根据您正在查看的路由,computedMiddleware将始终应用verifyorganizationslug个中间件,并且应用控制器中为该路由指定的其他中间件。

Route controller getMiddleware filters all middleware not belonging in that method

public function getMiddleware($controller, $method)
{
    if (! method_exists($controller, 'getMiddleware')) {
        return [];
    }
    return collect($controller->getMiddleware())->reject(function ($data) use ($method) {
        return static::methodExcludedByOptions($method, $data['options']);
    })->pluck('middleware')->all();
}

重要

现在,您的代码围绕请求响应Pipeline运行,以确保按照上述顺序应用中间件。您将控制器中间件的应用程序丢失为isControllerAction returns false,因为它是Closure而不是string

快进,你想使用:

Route::get('/{organization_slug}', '\App\Http\Controllers\FooController@details')
     ->middleware('foo');

然后解析控制器内的organization_slug

public function details(Request $request, $organisation_slug)
{
   $organization = \App\Organization::where('slug', '=', $organization_slug)
                       ->first();
   ...
}

或者考虑使用Route bindingorganization_slug路由参数绑定到组织的实例.✌️