與 Laravel 一樣,從進入點 index.php 開始看起。
$app = require __DIR__.'/../bootstrap/app.php';
$app->run();
|
Lumen 顯得非常簡單,只有拿 Application 後,直接 run 即可。
而 bootstrap/app.php 如下:
require_once __DIR__.'/../vendor/autoload.php';
try { (new Dotenv\Dotenv(__DIR__.'/../'))->load(); } catch (Dotenv\Exception\InvalidPathException $e) { }
$app = new Laravel\Lumen\Application( realpath(__DIR__.'/../') );
$app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );
$app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class );
$app->router->group([ 'namespace' => 'App\Http\Controllers', ], function ($router) { require __DIR__.'/../routes/web.php'; });
return $app;
|
回顧之前分析 bootstrap,這裡多了載 .env 與註冊 route 兩件事。這意味著 Lumen Application 並沒有處理這兩件事。
載 .env 是 Bootstrapper LoadEnvironmentVariables 所初始化的,Router 則是在 App\Providers\RouteServiceProvider::boot() 的時候註冊的。
不僅如此,從註解的說明可以知道,Lumen 預設很多事都沒有做,如 ServiceProvider 需要從頭來;Middleware 也要重頭來;Facade 需要另外設定,等。
來看 Lumen Application 的建構子有多精簡:
public function __construct($basePath = null) { if (! empty(env('APP_TIMEZONE'))) { date_default_timezone_set(env('APP_TIMEZONE', 'UTC')); }
$this->basePath = $basePath;
$this->bootstrapContainer();
$this->registerErrorHandling();
$this->bootstrapRouter(); }
|
大致上,原本 Laravel 會跑的 Bootstrap 任務,全都精簡化放在這裡了。
最後就是執行 run()
方法,它寫在 RoutesRequests 這個 trait 裡:
public function run($request = null) { $response = $this->dispatch($request);
if ($response instanceof SymfonyResponse) { $response->send(); } else { echo (string) $response; }
if (count($this->middleware) > 0) { $this->callTerminableMiddleware($response); } }
|
從 Request 可以傳 null 可得知,這同時也是提供了方便測試的接口。
Slim 也可以這麼做。
明天再繼續看 dispatch()
方法裡面做了什麼。