記一次給 Laravel 5.3 的 Route 動手術

XiaohuiLam發表於2018-11-07

一個專案,架構是 Laravel 5.3,在重構路由繫結許可權的過程中,手記如下:

期望實現效果

Route::get('/test', 'TestController@index')->name('test')->permission(['admin', 'agent']); //在新增路由時候,就繫結入相應的許可權

新增單個路由繼承 (就是 Route::get() 等方法返回回來的物件,需要擴充套件下,Laravel 5.3 的 Illuminate\Routing\Route 不支援 Macroable 。)

<?php

namespace App\Routing;

class Route extends \Illuminate\Routing\Route
{
    /**
     * 給路由註冊許可權
     *
     * @param string|array $permissions
     * @return self|static|$this
     */
    public function permission($permissions)
    {
        // ...
    }
}

新增假面路由 Route::class 的繼承

<?php

namespace App\Routing;

class Router extends \Illuminate\Routing\Router
{
    /**
     * Create a new Route object.
     * 必須覆蓋此方法,否則::get/::post...建立出的路由將會是 Illuminate\Routing\Route 而不是 App\Routing\Route
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  mixed  $action
     * @return \App\Routing\Route
     */
    protected function newRoute($methods, $uri, $action)
    {
        $route = (new Route($methods, $uri, $action))
            ->setRouter($this)
            ->setContainer($this->container);

        $route->url = $uri;
        return $route;
    }
}

以上OK後,

研究 Route 假面得知,其在容器中的識別符號為 router
於是我在 app/Providers/AppServiceProvider.phpboot 方法新增了

app()->alias('router', \App\Routing\Router::class);

但是在 tinker 中驗證,發現

php artisan tinker
> get_class(app('router'))
> "Illuminate\Routing\Router`

才想起 Applicaiton 容器在初始化時候就會註冊路由。已經輪不到 App\Providers\AppServiceProvider 來替換繫結。

突然想起,bootstrap/app.php 繫結了不少別名,

於是,我把它挪到了 bootstrap/app.php 下。

正常了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章