Laravel中你為什麼可以直接在 web.php 中 直接使用 Route ? 服務提供者的介紹

gclove發表於2019-02-16

這篇文章來自一個 sf 社群問題的思考

laravel web.php 中 Route 為什麼可以直接使用


原理很簡單

1 . 首先, 你注意一下 /config/app.php 裡面

/*
    |--------------------------------------------------------------------------
    | Class Aliases
    |--------------------------------------------------------------------------
    |
    | This array of class aliases will be registered when this application
    | is started. However, feel free to register as many as you wish as
    | the aliases are "lazy" loaded so they don`t hinder performance.
    |
    */
    `aliases` => [
        `Route` => IlluminateSupportFacadesRoute::class,
    ];

2 . 因為有 Facades, 所以我們直接去看 IlluminateSupportFacadesRoute::class 這個類返回的內容

* @method static IlluminateRoutingRoute get(string $uri, Closure|array|string $action)

/**
 * Get the registered name of the component.
 *
 * @return string
 */
protected static function getFacadeAccessor()
{
    return `router`;
}

3 . 那就簡單了, 直接去找註冊為 router 的元件

發現是在 Illuminate/Routing/RoutingServiceProvider.php

/**
 * Register the router instance.
 *
 * @return void
 */
protected function registerRouter()
{
    $this->app->singleton(`router`, function ($app) {
        return new Router($app[`events`], $app);
    });
}

4 . new Router() 看到了沒, 很顯然就會返回 Illuminate/Routing/Router.php 例項; 是不是發現了

   /**
     * Register a new GET route with the router.
     *
     * @param  string  $uri
     * @param  Closure|array|string|null  $action
     * @return IlluminateRoutingRoute
     */
    public function get($uri, $action = null)
    {
        return $this->addRoute([`GET`, `HEAD`], $uri, $action);
    }

(づ ̄3 ̄)づ╭❤~ 宣我 !! 麼麼


問答時間

1) . 我確認了 `router` 是在
Illuminate/Routing/RoutingServiceProvider.php 裡面的 ,

但是為什麼沒有配置在 /config/app.phpproviders 裡面呢

答案在這裡

Illuminate/Foundation/Application.php

注意 base service providersconfigured providers



    /**
     * Register all of the base service providers.
     *
     * @return void
     */
    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));

        $this->register(new LogServiceProvider($this));

        $this->register(new RoutingServiceProvider($this));
    }
    
    

   /**
     * Register all of the configured providers.
     *
     * @return void
     */
    public function registerConfiguredProviders()
    {
        (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                    ->load($this->config[`app.providers`]);
    }

2) . 那我看到在 /config/app.php 註冊了一個看起來像路由相關的 AppProvidersRouteServiceProvider::class, 它是幹嘛用的呢?

答案在這裡

首先 AppProvidersRouteServiceProvider 繼承自 IlluminateFoundationSupportProvidersRouteServiceProvider; (並且呼叫了我們上面的 IlluminateSupportFacadesRoute, 可以使用 Route::* )

直接看看 IlluminateFoundationSupportProvidersRouteServiceProvider 你就會明白


    public function boot()
    {
        $this->setRootControllerNamespace();

        if ($this->app->routesAreCached()) {
            $this->loadCachedRoutes();
        } else {
            $this->loadRoutes();

            $this->app->booted(function () {
                $this->app[`router`]->getRoutes()->refreshNameLookups();
                $this->app[`router`]->getRoutes()->refreshActionLookups();
            });
        }
    }
    
    public function register()
    {
        // 沒有在這裡註冊
    }

providers文件

boot 方法是在所有服務提供者都註冊完成後呼叫的方法, 所以說 這是啟動後 註冊路由的 provider

相關文章