iT邦幫忙

2019 iT 邦幫忙鐵人賽

0
Software Development

Laravel 原始碼分析系列 第 44

分析 Lumen Application--dispatch() 下篇

繼續看 RoutesRequests 下面的方法:

  • createDispatcher()
  • sendExceptionToHandler()
  • prepareResponse()

createDispatcher()

Lumen 並沒有使用 Laravel 的 Routing,而是使用自定義的 Router,把 Router 和 FastRoute 結合的就是這個方法:

protected function createDispatcher()
{
    return $this->dispatcher ?: \FastRoute\simpleDispatcher(function ($r) {
        foreach ($this->router->getRoutes() as $route) {
            $r->addRoute($route['method'], $route['uri'], $route['action']);
        }
    });
}

simpleDispatcher 是 FastRoute 提供 Dispatcher 的工廠方法。傳入的 $r 會是 FastRoute 專用的 RouteCollection。可以看到它使用 addRoute() 把 Lumen Router 存放的 Route 再轉存到 FastRoute Collection 裡。

最後 dispatcher 屬性,將會是 FastRoute 的 Dispatcher。

sendExceptionToHandler()

protected function sendExceptionToHandler($e)
{
    // 這裡將會取得 ExceptionHandler 實例
    $handler = $this->resolveExceptionHandler();

    // 轉換 Error 為 FatalThrowableError
    if ($e instanceof Error) {
        $e = new FatalThrowableError($e);
    }

    // 這裡的 report 與 render 和 Laravel 的使用方法大同小異
    $handler->report($e);

    return $handler->render($this->make('request'), $e);
}

Laravel 的 ErrorHandler 分析可以參考 Day31 分析自定義錯誤頁

prepareResponse()

Laravel 也有 prepareResponse(),Lumen 就像是精簡版一樣:

public function prepareResponse($response)
{
    $request = app(Request::class);

    // 轉換 Responsable
    if ($response instanceof Responsable) {
        $response = $response->toResponse($request);
    }

    // 轉換 PSR7 Response
    if ($response instanceof PsrResponseInterface) {
        $response = (new HttpFoundationFactory)->createResponse($response);
        
    // 若不是 Symfony Response 的實例,則預期會是字串,直接依字串產生 response
    } elseif (! $response instanceof SymfonyResponse) {
        $response = new Response($response);

    // 轉換 BinaryFileResponse
    } elseif ($response instanceof BinaryFileResponse) {
        $response = $response->prepare(Request::capture());
    }

    // 處理 Header 後回傳
    return $response->prepare($request);
}

以上就是 dispatch() 詳細分析的過程,接著明天再來看 Router 的實作。


上一篇
分析 Lumen Application--dispatch() 上篇
下一篇
分析 Laravel Feature Test
系列文
Laravel 原始碼分析46

尚未有邦友留言

立即登入留言