vendor\laravel\framework\src\Illuminate\View
是視圖模塊所在的文件夾,如未說明類所在文件位置則指此文件夾。php
在使用視圖相關的功能以前是須要作些準備的,準備天然是在服務提供者類運行的(在app\config.php
的providers中定義了應用中的服務提供者類),從中咱們能夠看出Illuminate\View\ViewServiceProvider::class
指的就是ViewServiceProvider
類,所以在ViewServiceProvider
類中會註冊一些須要用到的依賴到容器,注入名稱和實例以下:laravel
view.engine.resolver EngineResolver php PhpEngine blade CompilerEngine blade.compiler BladeCompiler view.finder FileViewFinder view Factory
這個時候咱們已經能夠看出Factory
是視圖模塊重要的類了,由於Laravel會從容器中取出view.engine.resolver, view.finder, events(這個類是其餘地方注入到容器中的)中的對象做爲參數傳遞給Factory
,而php和blade雖然並無注入到容器,倒是做爲EngineResolver
的屬性$resolvers
的值的。
FactoryFactoryEngineResolver$resolvers
上一步驟只是作了些視圖運行前的準備,而並無真的運行視圖的功能,通常運行是從view()
開始的,這是一個全局的方法,這個方法是定義在vendor\laravel\framework\src\Illuminate\Foundation\helpers.php
中的,這裏其實調用了Factory
的make()
,這個方法其實主要是對傳入的參數作處理並用這些參數初始化View
類,再返回View
的實例。緩存
對的處理還涉及到和的處理,不理會這個咱們是知道視圖其實返回的應該是字符串的纔對。對象轉字符串天然使用的是魔術方法,這裏並不直接返回字符串,而是經過一系列的調用最終是在中返回,這裏的engine是,即上面View實例化的時候傳遞的第二個參數(也是的實現),由於Laravel的視圖文件的名稱包含blade,因此實例化的是。事實上這和容器中名爲view.engine.resolver的類實例有關,具體細節能夠在中找。$this->callCreator($view = new View($this, $this->getEngineFromPath($path), $view, $path, $data)); return $view;ViewRouterResponse__toString()getContents()$this->engine->get()CompilerEngineEngineInterfaceCompilerEnginegetEngineFromPath()
CompilerEngine
的$compiler
纔是實際把視圖文件轉成字符串的主力。通常的$compiler
的實例是BladeCompiler
,這個就是把Blade語法(Blade是Laravel內置模版引擎的名字)轉換成PHP語法的核心。app
無論上面的步驟如何的繞來繞去,把視圖文件編譯成字符串纔是BladeCompiler
類的主場功能,這個類纔是真正的苦力工做者。BladeCompiler
實現了CompilerInterface
接口,這個接口真正工做是compile()
,compile()
把視圖文件編譯成PHP的原生語法的字符串並寫入到緩存目錄的文件中,而getCompiledPath()
根據視圖文件的路徑來獲取編譯後的文件的路徑。ide
編譯使用token_get_all()
來進行語法的解析,當碰到PHP標記爲T_INLINE_HTML
(T_INLINE_HTML
標記其實就是code沒法直接解析成PHP而把這段code看成一段嵌套的HTML,這裏通常就是指Blade語法的Code)的PHP標記時用對應的方法進行語法的替換,直到最終沒有PHP標記爲T_INLINE_HTML
爲止。this
沒法直接編譯的code分爲4類,分別是擴展,語句,註釋,輸出,這個從$compilers
中能夠看出,咱們能夠稱$compilers
爲內部編譯器,每一個內部編譯器對應一個相應的解析方式,如註釋編譯器對應compileComments()
。.net
這裏就把Blade語法的code變成原生PHP語法的code了。 從中不難看出就是把Blade語法翻譯成PHP原生語法的實現。固然這是最簡單的內部編譯器,像語句,輸出內部編譯器的實現就複雜的多,但只是實現複雜,涉及到正則的解析和不一樣形式的語句的解析,原理仍是同樣的。/** * Compile Blade comments into valid PHP. * * @param string $value * @return string */ protected function compileComments($value) { $pattern = sprintf('/%s--((.|\s)*?)--%s/', $this->contentTags[0], $this->contentTags[1]); return preg_replace($pattern, '<?php /*$1*/ ?>', $value); }{{-- This comment will not be present in the rendered HTML --}}<?php /*This comment will not be present in the rendered HTML*/ ?>