Blade 模板引擎入門篇

一、Blade 概述

視圖文件緊密關聯的就是模板代碼,咱們在視圖文件中經過模板代碼和 HTML 代碼結合實現視圖的渲染。和不少其餘後端語言不一樣,PHP 自己就能夠當作模板語言來使用,可是這種方式有不少缺點,好比安全上的隱患、容易產生業務邏輯與視圖模板的耦合,並且在視圖文件中處處使用 <?php 內聯代碼一點都不優雅,甚至是 ugly code,因此你會看到絕大多數現代框架都會提供一套模板引擎,好比 Smarty,Twig,以及 Laravel 使用的 Blade。php

注:不一樣於其餘基於 Symfony 的 PHP 框架,Laravel 沒有使用 Twig 模板引擎,不過你想要使用的話,能夠藉助 TwigBridge 擴展包來實現。html

Blade 模板引擎是由 Laravel 框架提供的自有實現,借鑑了 .NET 的 Razor 引擎語法,其語法簡潔,易於上手,同時提供了強大而直觀的繼承模型,並且方便擴展。下面是一個簡單的 Blade 模板代碼示例:前端

<h1>{{ $group->title }}</h1> 
{!! $group->imageHtml() !!} 
@forelse ($users as $user) 
    {{ $user->username }} {{ $user->nickname }}<br> 
@empty 
    該組中沒有任何用戶 
@endforelse

正如你所看到的,Blade 模板引擎有三種常見的語法:vue

  • 經過 {{ }} 渲染 PHP 變量(最經常使用)web

  • 經過 {!! !!} 渲染原生 HTML 代碼(用於富文本數據渲染)後端

  • 經過以 @ 做爲前綴的 Blade 指令執行一些控制結構和繼承、引入之類的操做緩存

下面咱們就來逐一介紹這些語法。安全

注:Blade 模板代碼存放在以 .blade.php 後綴結尾的視圖文件中,最終會被編譯爲原生 PHP 代碼,並緩存起來,直到視圖模板有修改纔會再次編譯,因此擁有與原生 PHP 幾乎一致的性能,這些編譯後的代碼位於 storage/framework/views 目錄下。你固然能夠在 Blade 模板中使用原生 PHP 代碼,可是不建議這麼作,若是你非要這麼作的話,能夠經過 @php 指令引入。前端框架

二、渲染數據

首先咱們來看一下 {{}} 語法,咱們經過經過該語法包裹須要渲染的 PHP 變量,如 {{ $variable }},你能夠將其類比爲 <?php echo $variable; ?>,可是 Blade 模板代碼的功能要更強大,經過 {{}} 語法包裹渲染的 PHP 變量會經過 htmlentities() 方法進行 HTML 字符轉義,從而避免相似 XSS 這種攻擊,提升了代碼的安全性,因此 {{ $variable }} 編譯後的最終代碼是:微信

<?php echo htmlentities($variable); ?>

可是某些狀況下不能對變量中 HTML 字符進行轉義,好比咱們在表單經過富文本編輯器編輯後提交的表單數據,這種場景就須要經過 {!! !!} 來包裹待渲染數據了:

{!! $variable !!}

這樣編譯後的代碼就是 <?php echo $variable; ?> 了。

注:對於富文本數據 XSS 攻擊防禦,能夠參考這篇教程:https://xueyuanjun.com/post/9476.html

最後,關於數據變量渲染,咱們還要注意的是,不少前端框架也是經過 {{}} 來輸出 JavaScript 變量數據的,好比 Laravel 的好基友 Vue.js 就是,對於這種狀況,咱們須要在渲染前端 JavaScript 變量的 {{}} 前面加上 @ 前綴,這樣,Blade 模板引擎在編譯模板代碼的時候會跳過帶 @ 前綴的 {{}} 數據渲染,並將 @ 移除從而能夠後續執行對應的 JavaScript 框架渲染邏輯:

// Blade 引擎會將其編譯爲對應的 PHP 代碼
{{ $phpData }}
// Blade 引擎編譯時會移除 @,保留 {{ $vueData }} 結構
@{{ $vueData }}

若是要註釋一段 PHP 代碼,能夠經過 {{-- 註釋內容 --}} 實現。

三、控制結構

Blade 中的控制結構語法和 PHP 大同小異,學習成本幾乎爲零,不過 Blade 爲咱們額外提供了一些有用的輔助變量和方法,方便咱們進行條件判斷。

條件語句

@if、@else、@elseif

Blade 模板中的 @if 等價於 PHP 的 <?php if ($condition):@else@elseif 依次類推,最後以一個 @endif 收尾:

@if (count($students) === 1
    操場上只有一個同窗
@elseif (count($students) === 0)
    操場上一個同窗也沒有
@else
    操場上有 {{ count($students) }} 個同窗
@endif

和原生 PHP 中的用法一模一樣。

@unless

@unless 是 Blade 提供的一個 PHP 中沒有的語法,用於表示和 @if 條件相反的條件,@unless($condition) 能夠理解爲 <?php if (!$condition):,而後以 @endunless 收尾:

@unless ($user->hasPaid()) 
    用戶沒有支付
@endunless

@isset、@empty

這兩個指令和 PHP 中的 isset()empty() 方法等價:

@isset($records)
    // 記錄被設置
@endisset

@empty($records)
    // 記錄爲空
@endempty

後面兩個都是語法糖,若是你不想記太多東西,不防都用 @if 來實現對應的邏輯了。

@switch

顧名思義,Blade 中的 @switch 指令和 PHP 中的 switch 語句等價,咱們能夠經過 @switch@case@break@default@endswitch 指令構建對應邏輯:

@switch($i)
    @case(1)
        // $i = 1 作什麼
        @break

    @case(2)
        // $i = 2 作什麼
        @break

    @default
        // 默認狀況下作什麼
@endswitch

循環結構

@for、@foreach 和 @while

和 PHP 同樣,在 Laravel 中,咱們能夠經過與之等價的 @for@foreach@while 實現循環控制結構,使用語法和 PHP 代碼相仿:

// for 循環
@for ($i = 0; $i < $talk->slotsCount(); $i++) 
    The number is {{ $i }}<br> 
@endfor

// foreach 循環
@foreach ($talks as $talk)
    {{ $talk->title }} ({{ $talk->length }} 分鐘)<br> 
@endforeach

// while 循環  
@while ($item = array_pop($items)) 
    {{ $item->orSomething() }}<br> 
@endwhile

@forelse

這個指令是 PHP 中具有的,能夠理解爲處理如下 PHP 代碼邏輯:

<?php 
if ($students) {
    foreach ($students as $student) {
       // do something ...
    }
else {
    // do something else ...
}

在 Blade 模板中咱們可使用 @forelse 指令經過如下代碼實現上述邏輯:

@forelse ($students as $student)
    // do something ...
@empty
    // do something else ...
@endforelse    

@foreach 和 @forelse 中的 $loop 變量

在循環控制結構中,咱們要重磅介紹的就是 Blade 模板爲 @foreach@forelse 循環結構提供的 $loop 變量了,經過該變量,咱們能夠在循環體中輕鬆訪問該循環體的不少信息,而不用本身編寫那些惱人的麪條式代碼,好比當前迭代索引、嵌套層級、元素總量、當前索引在循環中的位置等,$loop 實例上有如下屬性能夠直接訪問:

下面是一個簡單的使用示例:

<ul> 
@foreach ($pages as $page)
    @if ($loop->first)
        // 第一個循環迭代
    @endif 
    <li>{{ $loop->iteration }}: {{ $page->title }} 
        @if ($page->hasChildren()) 
        <ul> @foreach ($page->children() as $child) 
            <li>{{ $loop->parent->iteration }}. {{ $loop->iteration }}: {{ $child->title }}</li> 
            @endforeach 
        </ul> 
        @endif 
    </li> 
    @if ($loop->last)
        // 最後一個循環迭代
    @endif
@endforeach 
</ul>

有了這個 $loop 變量,確實可以幫咱們節省不少重複的邏輯判斷和編碼工做,推薦使用。

(全文完)

長按下面的二維碼,便可訂閱學院君最新發布的 Laravel 入門系列教程:

關於本系列教程的更多動態,請點擊頁面左下角的「閱讀原文」連接查看。

本文分享自微信公衆號 - xueyuanjun(geekacademy)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索