非常好用的PHP模板引擎

shooke發表於2017-11-14

什麼是模板引擎

顧名思義,這是個模板解析的工具。他是為了解決mvc,實現資料和展示分離問題而產生的。php模板引擎由來已久,比如老大哥smarty。已經很少有人用了。畢竟現在mvc已經很成熟,很多框架都有自己的模板引擎。比如Symfony的twig,Laravel的blade。

效能損耗?

模板引擎開始出現的時候,有很多人質疑,認為有效能問題。但其實這是沒有必要的。畢竟模板引擎只是編譯一次,把相應的模板語法利用正則替換成php語句,然後儲存成php檔案就完成任務了,後續的執行其實是載入php檔案。多出來的僅僅是一個是否存在編譯檔案的判斷而已。對於現在的計算速度來說可以忽略。

為什麼要用模板引擎

1 從繁瑣的php標籤中脫離出來,從而提高程式碼的可讀性
2 將資料處理和檢視展示分離,檢視只負責展示和基本的邏輯判斷
3 很好的進行檢視拆分,組織結構

模板引擎比較

除了目的,還有一個不可忽視的問題,是否易學,如果一個模板引擎需要用幾個小時去學習,那這樣的學習成本太高了。作為一個工具應該簡單易學,其次是能滿足需求,功能要完善。
看一下比較主流的模板引擎的使用

twig,他的使用語法我比較喜歡,很容易看懂,簡單易學

基本語法
{% for user in users %}
    * {{ user.name }}
{% else %}
    No users have been found.
{% endfor %}

指定佈局檔案
{% extends "layout.html" %}
定義展示塊
{% block content %}
    Content of the page...
{% endblock %}複製程式碼

再看看blade

<!-- 檔案儲存於 resources/views/layouts/app.blade.php -->

<html>
    <head>
        <title>應用程式名稱 - @yield('title')</title>
    </head>
    <body>
       @section('sidebar')
            這是 master 的側邊欄。
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

<!-- Stored in resources/views/child.blade.php -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @parent

    <p>This is appended to the master sidebar.</p>
@endsection

@section('content')
    <p>This is my body content.</p>
@endsection複製程式碼

上面可以看出,blade就比twig複雜多了,如果不看說明,你沒法理解上面程式碼的意思。為什麼沒有累出smarty,因為它更復雜,現在使用的人也比較少了。

我們總結以下,一個模板引擎應該具備以下功能
1 資料塊block/section 這是一個很強大的功能,可以靈活的控制每一個展示塊
2 繼承機制parent 使用parent繼承呼叫佈局中的內容塊
3 多檔案組合include 利用include可以將多個模板組合到一起,實現多種不同場景下的程式碼複用
4 靈活的變數函式以及常量使用
5 優雅的標籤邏輯控制 你可以充分利用ide軟體的程式碼提示和自動完成功能,而不需要安裝特殊外掛
6 模板自動監聽 當模板更新時,重新整理頁面,模板引擎會自動進行編譯,展示最新內容

今天的主角

在具有上面總結的所有功能的前提下,看看今天的主角是怎麼解決易學,可讀這兩個難題的。

佈局

<!--佈局檔案的程式碼-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><block title>預設標題</block></title>
</head>
<body>
<!--展示塊定義-->
<block content>我是佈局模板content</block>
<!--引入模板-->
<include footer></include>
</body>
</html>

<!--內容模板-->

<!--展示塊定義,會覆蓋佈局中的站位-->
<block title>{{ $title }}</block>
<block content>
    我是內容模板,但是我用parent標籤,呼叫了佈局檔案中content的內容<br>
    <parent content></parent>
</block>複製程式碼

是不是清爽至極。定義不同的block標籤,靈活的控制內容和位置,內容模板的內容會預設覆蓋佈局檔案的相同block塊。還可以在內容模板,用parent標籤呼叫佈局檔案中的內容。

使用html標籤的方式進行程式碼書寫,可以在所有ide軟體中實現程式碼不全。上面的程式碼實現了展示塊定義,內容模板展示塊覆蓋佈局模板,以及繼承和,外部引入include。

變數 常量 函式的使用

當然,除了對模板的總體管理,模板中還要有流程控制和變數輸出。

//變數
{{ $title }}
// 函式
{{ date('Y-m-d') }}
//普通常量跟變數用法一致,需要用{{}}括起來
{{ CONST_VAR }} 

//兩邊下劃線的常量直接使用
//會翻譯為< ?php if(defined('__APP__')){echo __APP__;}else{echo '__APP__';} ?>
__APP__ 

// 三目運算
{{ $a==0 ? 0 : 1 }}複製程式碼

流程控制

if判斷

        <if$var>1)>
            大於1
        <elseif ($var==1)>
           等於1
        <else/>
            小於1
        </if>複製程式碼

for迴圈


        <for ($i=0;$i<5;$i++)>
            {{ $i }}
        </for>
        普通當然for迴圈複製程式碼

for in


        <for $item in $array>
            {{ $item['title'] }}
        </for>
        相當於foreach($array as $item)

        <for ($item,$index) in $array>
            {{ $index }}=>{{ $item['title'] }}
        </for>
        相當於foreach($array as $index=>$item)複製程式碼

foreach 跟源生php寫法對應只是換成了php標籤形式

        <foreach ($array as $item)>
            {{ $item['title'] }}
        </foreach>
        <foreach ($array as $index=>$item)>
            {{ $index }}=>{{ $item['title'] }}
        </foreach>複製程式碼

php中初始化

include "../Template.php";
$view = new Template();
$view->templatePath = './template/';// 模板路徑 最後以/結尾
$view->compilePath = './compile/';// 編譯檔案存放路徑 最後以/結尾
$view->layout = 'layout';// 佈局檔案在末班目錄下,如果不適用可以定義成空字串或false

// 渲染模板
$view->render('index',[
    'title'=>'測試頁',
    'content'=>'內容',
    'array'=>[
        1,2,3
    ]
]);
//清空快取
//$view->clean();複製程式碼

喜歡的朋友歡迎star github.com/shooke/temp…

相關文章