老司機帶你深入分析 Laravel 響應之一

Dennis_Ritchie發表於2020-01-06

前言

本來在上一篇部落格中,我已經決定不再寫關於Laravel原始碼的文章了,但是上週六突然無緣無故被噴了一波(我也很懵逼,哪裡都有這種奇葩,這都能被噴),所以這周我繼續講下去。這篇要講的內容承接自上一篇《老當機帶你深入理解 Laravel 之驗證器下
》,所以如果你要閱讀本篇博文,請自行閱讀上一篇。

Laravel響應之深入分析

我們直接來到類Illuminate\Routing\RouterrunRouteWithinStack方法(如果不清楚,所以我建議你看《老當機帶你深入理解 Laravel 之驗證器下
》):

Laravel響應之深入分析

$route->run()就是我們控制器的返回結果,比如我的DebugControllerdebug方法如下:

Laravel響應之深入分析

當我訪問這個方法時候,我們來測試一下,我們列印$route->run()的值,瀏覽器結果:

Laravel響應之深入分析

這裡呼叫了prepareResponse方法,它繼續呼叫toResponse方法,該方法如下:

Laravel響應之深入分析

因為在我們的控制器中,返回的是一個陣列,所以我們沿著這條線索進行分析(其它情況,後面再行分析),此時的$response就是Illuminate\Http\JsonResponse類的物件,緊接著呼叫prepare方法,Illuminate\Http\JsonResponse類繼承自Symfony\Component\HttpFoundation\JsonResponse類,Symfony\Component\HttpFoundation\JsonResponse類又繼承自Symfony\Component\HttpFoundation\Response類,繼承關係並不複雜,程式碼量也不大,自己有興趣的可以看哈。

前面說的prepare方法就屬於Symfony\Component\HttpFoundation\Response類的,我不打算分析這個方法,這個方法的作用就是設定響應的HTTP頭部,比如:Content-Type等。

經過了上面和之前幾篇的一系列分析,我們得到了$response響應物件,我們回到Laravel的入口檔案public/index.php檔案中:

Laravel響應之深入分析

這個時候,你可以列印下$response的類(比如:dd(get_class($response))):

Laravel響應之深入分析

繼續分析響應物件的send方法,這個方法也屬於Symfony\Component\HttpFoundation\Response類,很簡單:

Laravel響應之深入分析

方法sendHeaders用於傳送頭部,如下:

Laravel響應之深入分析

方法sendContent用於傳送響應的內容:

Laravel響應之深入分析

哈哈,就是這麼簡單粗暴。

send方法呼叫完之後,回到index.php檔案中:

Laravel響應之深入分析

$kernel就是Illuminate\Foundation\Http\Kernel類的物件,下面進入到terminate方法中:

Laravel響應之深入分析

方法terminateMiddleware用於執行我們定義的中介軟體:

Laravel響應之深入分析

如果你認真的閱讀過我之前寫的幾篇《老當機帶你深入理解 Laravel 之驗證器上(控制器引數解析)》和《老當機帶你深入理解 Laravel 之驗證器下》,就知道這段程式碼已經講過了,只是要提醒你的是每一箇中介軟體都可以實現terminate方法,這個方法在響應被髮送給客戶端之後,會被呼叫。

回到terminate方法中,呼叫$this->app->terminate()方法,app就是Illuminate\Foundation\Application類的物件:

Laravel響應之深入分析

terminatingCallbacks中的每一個元素都是一個回撥,我們可以通過呼叫appterminate方法新增回撥。

總結

我的天哪,終於簡要的走完了laravel的流程,但這是遠遠不夠的,因為我這裡分析的是控制器返回的是陣列型別,在後面的章節中,我會給大家分析其它的型別,包括檢視,三人行,必有我師焉,可以加入QQ群,進行討論:

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

如果有不懂的地方,可以加我的qq:1174332406,或者是微信:itshardjs

相關文章