Laravel5工作流程分析

初學(xué)Laravel難免對(duì)項(xiàng)目組織結(jié)構(gòu)疮胖、工作流程不太了解环戈,本文以盡量簡(jiǎn)單的方式向大家做大概介紹。

組織結(jié)構(gòu)說明

成功創(chuàng)建Laravel后澎灸,項(xiàng)目組織結(jié)構(gòu)如下圖所示院塞。

組織結(jié)構(gòu)

運(yùn)行效果

合理配置web服務(wù)器后運(yùn)行,正常運(yùn)行效果如下性昭。

運(yùn)行效果

啟動(dòng)流程分析

Laravel是如何展示上面網(wǎng)頁的呢拦止,下面我們來慢慢揭曉。
下圖為我簡(jiǎn)單整理的啟動(dòng)流程序列圖糜颠,估計(jì)不太清晰汹族,建議大家下載原圖查看。


laravel工作流程
備注:為了圖片簡(jiǎn)單其兴,上面序列圖中鞠抑,大部分函數(shù)調(diào)用的返回箭頭我是省略掉了,相信略有基礎(chǔ)的人應(yīng)該都可以看懂忌警。

一搁拙、創(chuàng)建App對(duì)象

在Laravel中一個(gè)app對(duì)象就是一個(gè)Container(服務(wù)容器,概念不清晰的推薦閱讀科普好文官方介紹),這就意味著app可以綁定各類Provider(服務(wù)提供者)法绵。
public/index.php是程序入口箕速,public/index.php中通過如下代碼創(chuàng)建一個(gè)app對(duì)象。

$app = require_once __DIR__.'/../bootstrap/app.php';

進(jìn)入bootstrap/app.php文件朋譬,我們看到如下代碼盐茎,該代碼創(chuàng)建了一個(gè)Application對(duì)象實(shí)例。

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

進(jìn)入Application源文件徙赢,我們可以看到這樣的類定義:

class Application extends Container implements ApplicationContract, HttpKernelInterface

可以看出來Application就是一個(gè)Container字柠,同時(shí)Application也繼承了ApplicationContract及HttpKernelInterface接口探越。
再深入一點(diǎn),我們可以看到ApplicationContract主要定義了一組獲取項(xiàng)目路徑窑业、環(huán)境信息钦幔、Provider(服務(wù)提供者)的接口,及程序啟動(dòng)相關(guān)的boot()常柄、booted()等接口鲤氢。而HttpKernelInterface主要定義了http相關(guān)的事件處理接口handle()。

二西潘、綁定服務(wù)

我們繼續(xù)閱讀bootstrap/app.php文件卷玉,可以看到如下代碼

//注冊(cè)一個(gè)App\Http\Kernel服務(wù)Class,這個(gè)類主要用于http相關(guān)事件處理
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);
//注冊(cè)一個(gè)App\Console\Kernel服務(wù)Class喷市,這里我還不太清楚該類的作用
$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);
//注冊(cè)異常處理Handler相种,沒深入去研究,看代碼基本上是接受到異常后還是交給父類處理
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

上面代碼中很關(guān)鍵的一個(gè)點(diǎn)是注冊(cè)App\Http\Kernel品姓,從上面流程圖你可以大致感覺到這個(gè)類的重要性蚂子。

如果你困惑為什么注冊(cè)的函數(shù)名叫singleton,建議你看看函數(shù)內(nèi)部實(shí)現(xiàn)缭黔,其實(shí)內(nèi)部就是調(diào)用的Container->bind()方法食茎,只是對(duì)外換了個(gè)名字而已。

通常馏谨,綁定并不會(huì)實(shí)例化對(duì)象别渔,綁定可以簡(jiǎn)單理解為通過一個(gè)字典將interface跟具體的class(或匿名函數(shù)Closure)關(guān)聯(lián)起來,其中字典的key就是interface的名字惧互,字典的value就是class名字哎媚,理解這一點(diǎn)非常重要,因?yàn)檫@是Container實(shí)現(xiàn)di(dependency injection依賴注入)和ioc(Inversion Of Control控制反轉(zhuǎn))很重要的一環(huán)喊儡。

三垛玻、實(shí)例化各類服務(wù)及路由處理

回到public/index.php范删,我們看到如下代碼衷快。

//實(shí)例化一個(gè)kernel對(duì)象业筏。
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

上面代碼中app->make才是真正將App\Http\Kernel對(duì)象實(shí)例化。怎么實(shí)例化的呢匆赃?前面我們有講到淤毛,綁定就是將interface名跟與之對(duì)應(yīng)的class存入一個(gè)字典中,而make就是通過interface名找到對(duì)應(yīng)的class名算柳,并用反射機(jī)制創(chuàng)建對(duì)應(yīng)的class實(shí)例低淡。
kernel->handle()傳入一個(gè)request并返回一個(gè)response對(duì)象。別看這里只有一行代碼,實(shí)際上做的事情非常之多蔗蹋,該函數(shù)內(nèi)部調(diào)用的核心代碼如下:

protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);

        Facade::clearResolvedInstance('request');

        $this->bootstrap();

        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }

其中bootstrap()接口會(huì)調(diào)用app相關(guān)方法來實(shí)例化LoadConfiguration何荚、BootProviders、RegisterProviders等對(duì)象猪杭。
app對(duì)象通過讀取config/app.php配置文件來設(shè)置App\Providers\RouteServiceProvider餐塘、
App\Providers\AppServiceProvider等。

   'providers' => [
        //是的胁孙,為了簡(jiǎn)潔唠倦,這里我刪除了一些系統(tǒng)默認(rèn)provider称鳞,大家可以去查閱源碼
        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

    ],

獲取完配置信息之后app會(huì)初始化一個(gè)App\Providers\RouteServiceProvider對(duì)象涮较,并調(diào)用其boot()方法,boot()最終會(huì)設(shè)置好程序的路由映射關(guān)系。
RouteServiceProvider是很重要的一個(gè)類冈止,我們看下路由映射關(guān)系代碼狂票。

    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }

通過代碼我們發(fā)現(xiàn),web接口對(duì)應(yīng)的路由配置文件是routes/web.php熙暴。
打開routes/web.php闺属,我們可以看到如下代碼。

Route::get('/', function () {
    return view('welcome');
});

從代碼我們大致能夠猜測(cè)周霉,當(dāng)用戶訪問網(wǎng)站首頁的時(shí)候?qū)⒎祷匾粋€(gè)'welcome'頁面掂器,而這個(gè)頁面實(shí)際上就是resources/views/welcome.blade.php。我們可以debug一下view()俱箱,其內(nèi)部有一組規(guī)則將'welcome'映射到welcome.blade.php文件国瓮。
設(shè)置好路由之后kernel對(duì)象會(huì)調(diào)用dispatchToRouter(),并最終生成一個(gè)response對(duì)象狞谱,response對(duì)象里面包含welcome.blade.php返回的網(wǎng)頁數(shù)據(jù)乃摹。

輸出內(nèi)容

在回到public/index.php,下面的事情就變得簡(jiǎn)單跟衅。

//將頁面內(nèi)容輸出到調(diào)用者(這里指瀏覽器)
$response->send();
//掃尾工作
$kernel->terminate($request, $response);

以上是Laravel工作流程的分析孵睬,如果感覺還是不太理解,建議認(rèn)真閱讀Laravel中文手冊(cè)伶跷。
同時(shí)也推薦大家看看如下推薦文章掰读,不同的作者有不同的介紹方式,個(gè)人感悟也可能不一樣叭莫。
http://www.reibang.com/p/509a8dd5654e
http://www.reibang.com/p/63a3d76e7aca

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末磷支,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子食寡,更是在濱河造成了極大的恐慌雾狈,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抵皱,死亡現(xiàn)場(chǎng)離奇詭異善榛,居然都是意外死亡辩蛋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門移盆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悼院,“玉大人,你說我怎么就攤上這事咒循【萃荆” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵叙甸,是天一觀的道長(zhǎng)颖医。 經(jīng)常有香客問我,道長(zhǎng)裆蒸,這世上最難降的妖魔是什么熔萧? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮僚祷,結(jié)果婚禮上佛致,老公的妹妹穿的比我還像新娘。我一直安慰自己辙谜,他們只是感情好俺榆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著装哆,像睡著了一般罐脊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烂琴,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天爹殊,我揣著相機(jī)與錄音,去河邊找鬼奸绷。 笑死梗夸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的号醉。 我是一名探鬼主播反症,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼畔派!你這毒婦竟也來了铅碍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤线椰,失蹤者是張志新(化名)和其女友劉穎胞谈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烦绳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年卿捎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片径密。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡午阵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出享扔,到底是詐尸還是另有隱情底桂,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布惧眠,位于F島的核電站籽懦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锉试。R本人自食惡果不足惜猫十,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一览濒、第九天 我趴在偏房一處隱蔽的房頂上張望呆盖。 院中可真熱鬧,春花似錦贷笛、人聲如沸应又。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽株扛。三九已至,卻和暖如春汇荐,著一層夾襖步出監(jiān)牢的瞬間洞就,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工掀淘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旬蟋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓革娄,卻偏偏與公主長(zhǎng)得像倾贰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拦惋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理匆浙,服務(wù)發(fā)現(xiàn),斷路器厕妖,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,079評(píng)論 25 707
  • core package 概要:Core是所有其他包的基礎(chǔ)包.它提供了大部分功能包括metadata首尼,templa...
    LOVE小狼閱讀 2,576評(píng)論 0 3
  • 與摩拜單車創(chuàng)始人胡瑋煒的自行車情愫相比,我覺得自行車就是我的死敵!它根本不被我駕馭软能,我不讓我馴服挠羔,它不是我的好朋友...
    銀珠珠閱讀 334評(píng)論 0 0
  • 文:ShakespeareSky(莎士比亞斯基) 第三節(jié) 運(yùn)動(dòng)會(huì) 11月3日召開一年一度的秋季運(yùn)動(dòng)會(huì),這運(yùn)動(dòng)會(huì)開得...
    ShakespeareSky閱讀 567評(píng)論 0 0