本文是基於Laravel 5.4
版本的View
模塊代碼進行分析書寫;php
View
模塊的文件格局及功能以下圖所示:
css
視圖化呈現時的大概流程:html
view()
方法的調用,開始視圖的呈現;::
以前的部分),則採用命名空間對應註冊的路徑數組,不然採用全局路徑數組(在Illuminate\View\FileViewFinder
類中的paths
變量);blade.php
、php
、css
),判斷文件是否存在;view
文件不存在;若是文件存在,則根據後綴名調用對應的引擎進行解析;css
後綴,採用file
引擎,核心調用方法是file_get_contents
;若是是php
後綴,採用php
引擎,核心調用方法是前端
ob_start(); include $__path; ob_get_clean();
blade.php
後綴,採用blade
引擎;sha1
生成緩存文件(位於storage/framework/views
目錄下);Blade
引擎對文件的編譯,是經過大量的正則匹配和替換實現的;laravel
protected $compilers = [ 'Comments', // 註釋部分 'Extensions', // 擴展部分 'Statements', // 語句塊 (@ 開頭的指令) 'Echos', // 輸出 ]; protected function parseToken($token) { list($id, $content) = $token; if ($id == T_INLINE_HTML) { foreach ($this->compilers as $type) { $content = $this->{"compile{$type}"}($content); } } }
在解析的過程當中,Blade
會先使用token_get_all
函數獲取視圖文件中的被PHP
解釋器認爲是HTML
(T_INLINE_HTML
)的部分,而後依次進行Comments
、Extensions
、Statements
和 Echos
部分的正則替換;segmentfault
註釋部分
核心代碼以下,將註釋符號「{{-- --}}」包裹的代碼替換爲空字符串;數組
preg_replace("/{{--(.*?)--}}/s", '', $value);
擴展部分
經過extend
方法向BladeCompiler
添加自定義處理的回調函數,對模板內容進行自定義的文本匹配替換;緩存
核心代碼在Illuminate\View\BladeCompiler
文件中,以下:app
// 自定義的文本替換擴展 數組 protected $extensions = []; protected function compileExtensions($value) { foreach ($this->extensions as $compiler) { $value = call_user_func($compiler, $value, $this); } return $value; }
指令替換
這部分就是將相似@if
這種框架自帶的指令和經過directive
方法註冊的指令進行文本替換;框架
框架提供的指令有如下十部分:
View\Compilers\Concerns\CompilesAuthorizations
: 權限檢查@can
、@cannot
、@elsecan
、@elsecannot
、@endcan
、@endcannot
Concerns\CompilesComponents
:與組件、插槽相關@component
、@endcomponent
、@slot
、@endslot
Concerns\CompilesConditionals
:與判斷語句相關@if
、@unless
、@else
、@elseif
、@endif
、@endunless
、@isset
、@endisset
、@hassection
Concerns\CompilesIncludes
:嵌入文件@each
、@include
、@includeif
、@includewhen
Concerns\CompilesInjections
:服務注入@inject
Concerns\CompilesLayouts
:和佈局相關@extends
、@section
、@parent
、@yield
、@show
、@append
、@overwrite
、@stop
、@endsection
Concerns\CompilesLoops
:與循環相關@forelse
、@empty
、@endforelse
、@endempty
、@for
、@foreach
、@break
、@continue
、@endfor
、@endforeach
、@while
、@endwhile
Concerns\CompilesRawPhp
:與原生PHP語句相關@php
、 @endphp
、 @unset
Concerns\CompilesStacks
:和堆棧相關@stack
、@push
、@endpush
、@prepend
、@endprepend
Concerns\CompilesTranslations
:與本地化翻譯相關@lang
、@endlang
、@choice
Echo 替換echo
輸出是針對{!! !!}
、{{ }}
、{{{ }}}
三種括號進行正則替換;
{!! !!}
輸出未轉義字符,用於輸出原生帶html
標籤的值;{{ }}
正常輸出,支持三目運算符替換;{{{ }}}
輸出轉義字符,支持三目運算符替換;三目運算符替換是指:
{{ $a ?: "默認值" }}
(或者{{$a or "默認值"}}
) 換成{{ isset($a) ? $a : "默認值"}}