Lumen 切換 nikic/fast-route 為 illuminate/routing

mowangjuanzi發表於2020-06-24

為啥會有這個想法呢?原因有如下幾個:

  1. 元件已經許久不更新了。
  2. 元件在使用時有功能限制
  3. 在安裝 laravel 第三方元件時如果有相關 routing 功能可能會不支援一些功能,比如 Route:prefix()

好了,接下來就開始幹吧。

安裝之前先說一下注意事項:

  1. 該方法只適合使用自帶路由的情況。如果安裝了dingo/api的情況,情況並不適合。

下面我們就以 lumen7.0 為例進行講解。

首先安裝laravel的路由元件

composer require illuminate/routing

接下來我們要替換路由元件。通過讀取相關原始碼,我們知道註冊路由元件是通過Laravel\Lumen\Application::bootstrapRouter()進行註冊的。

所以接下來我們就是需要將該方法進行替換。

首先我們先建立一個檔案。目前就把檔案命名為app\Http\Kernel.php

然後將以下內容複製到該檔案:

// file: app\Http\Kernel.php
namespace App\Http;

use Illuminate\Routing\Router;
use Illuminate\Routing\RoutingServiceProvider;
use Laravel\Lumen\Application;

class Kernel extends Application
{
    /**
     * The Router instance.
     *
     * @var Router
     */
    public $router;

    /**
     * Bootstrap the router instance.
     *
     * @return void
     */
    public function bootstrapRouter() {
        $this->register(RoutingServiceProvider::class);
        $this->router = $this['router'];
        $this->router->middlewareGroup("web", []);
    }
}

然後替換bootstrap\app.php中例項化Application的方法。

$app = new \App\Http\Kernel(
    dirname(__DIR__)
);

執行一下,出現如下錯誤:

Cannot use object of type Illuminate\Routing\RouteCollection as array

這是在解析路由的時候出現了問題。

接下來我就再次重寫相關方法來實現該功能:

// file: app\Http\Kernel.php
namespace App\Http;

use Illuminate\Http\Response;
use Illuminate\Routing\Router;
use Illuminate\Routing\RoutingServiceProvider;
use Laravel\Lumen\Application;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;

class Kernel extends Application
{
    /**
     * The Router instance.
     *
     * @var Router
     */
    public $router;

    /**
     * Bootstrap the router instance.
     *
     * @return void
     */
    public function bootstrapRouter() {
        $this->register(RoutingServiceProvider::class);
        $this->router = $this['router'];
        $this->router->middlewareGroup("web", []);
    }

    /**
     * Dispatch the incoming request.
     *
     * @param  SymfonyRequest|null  $request
     * @return Response
     */
    public function dispatch($request = null)
    {
        $this->parseIncomingRequest($request);

        try {
            $this->boot();

            return $this->sendThroughPipeline($this->middleware, function ($request) {
                $this->app->instance('request', $request);

                return $this->router->dispatch($request);
            });
        } catch (\Throwable $e) {
            return $this->prepareResponse($this->sendExceptionToHandler($e));
        }
    }
}

再次執行一下,出現如下錯誤:

Undefined property: Illuminate\Routing\Router::$app

這是因為之前在路由檔案中$router是Laravel\Lumen\Routing\Router,目前已經更換為Illuminate\Routing\Router。該類中沒有相關方法。

那麼我們修改程式碼如下:

// file: routes\web.php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return app()->version();
});

這樣就替換成功了。

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

相關文章