phalcon模板引擎(volt)自定義過濾器

**引子:**今天遇到一個問題,模板中某些變量有時候沒有定義,若是php開啓了E_ALL報錯級別,那麼會出現一個notice,提示變量未定義。 一開始的想法是經過三元表達式(<?=isset($var)?$var:'';?>)來給每一個變量設定一個默認值,後來發現這種寫法太繁瑣,並且與volt標籤格格不入。 再後來想到屏蔽E_NOTICE報告,但開發環境下仍是很不恰當的。 最後發現volt引擎有一個過濾器Filters功能,解決了這個問題,寫法如:{{ var|default('str') }} ,在$var爲空的時候,將會將該處設置爲str,固然,str能夠是空字符串。 本文就探究一下什麼是過濾器,以及如何自定義過濾器。php

第一,模板渲染的是什麼? 在使用volt模板引擎的時候,模板是如何渲染的呢?你們都知道,在控制器方法執行完畢後,框架會自動渲染視圖View,而這時候因爲你使用了volt模板引擎,裏面特有的一套標籤語法並不是php語法,因此視圖沒法直接include模板文件而做爲php腳本解釋。這時候視圖會作一件事情,它會先將模板代碼中的標籤替換爲php代碼,保存到模板緩存文件中,緩存位置是你在di中配置視圖的時候本身設置的,每一個緩存文件都對應一個模板文件,第二次渲染視圖的時候將直接取緩存文件,避免了每次都要解析volt標籤,因此性能上與原生php模板並沒有差距,某些狀況下可能更好(佈局以及模板繼承時,會將多層模板合併爲一個,減小了文件讀取次數)。html

第二,標籤'原形' {{ var|default('str') }}究竟被轉化爲何?咱們能夠經過觀察模板緩存看到,這個標籤大概被轉化爲shell

<!-- lang: php -->
<?php echo (empty($var) ? ('str') : ($var)); ?>

第三,理解管道'|' 熟悉shell的朋友這一步一眼瞭然,標籤的做用機制是:將$var的值傳給下一個過濾器default處理,過濾器還可附加其餘參數,只要如同函數調用同樣增長參數便可,如上的 ('str');變量類型的標籤最終會轉化爲echo語句。數組

第四,自定義過濾器 經過官方手冊能夠知道,在di中註冊volt模板引擎的時候,能夠添加自定義的filter方法,先看一段代碼:瀏覽器

<!-- lang: php -->
//volt模板引擎服務
$di->set('voltService', function($view, $di) {
    $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
    $volt->setOptions(array(
        "compiledPath" => APP_PATH."/runtime/volt/",
        "compiledExtension" => ".compiled"
    ));
    //自定義過濾器
    $compiler = $volt->getCompiler();
    $compiler->addFilter('int', function($resolvedArgs, $exprArgs) {
        return 'intval(' . $resolvedArgs . ')';
    });
    return $volt;
});

上面咱們首先經過getCompiler拿到"編譯器對象"$compiler,在$compiler中經過addFilter添加自定義的過濾器,上面的代碼添加了一個叫作 "int" 的過濾器,其做用是將$var的值轉化爲整形。緩存

第五,理解 當volt模板解析的時候,假若有一個標籤{{ var|int }},這時候$compiler會檢查對象中有沒有int過濾器,顯然是有的,那麼會調用匿名函數,將返回值字符串放到echo 中,如上定義的int過濾器,最終返回的就是 intval($val),該標籤最終被替換爲框架

<!-- lang: php -->
<?php echo intval($val);?>

以後交由PHP解釋並返回html代碼到瀏覽器。 細節:$resolvedArgs是什麼? 它是變量名和附加參數的拼接,好比上面int沒有附加參數,那麼它的值就是 '$var',注意這裏是原義字符串,不要當成變量。 假設咱們定義了一個過濾器 trim,咱們想要 {{ var|trim('%') }}的結果爲 trim($val,'%')的值,那麼在定義過濾器匿名函數的時候就須要這麼寫函數

<!-- lang: php -->
$compiler->addFilter('concat', function($resolvedArgs, $exprArgs) {
    return 'trim('.$resolvedArgs.')';
});
return $volt;

也就是$resolvedArgs這個變量的值是:$val,'%' 注意,這裏是原義字符串,爲了表示方便,省略了兩邊的單引號,$var變量名永遠在開頭。 最終標籤被替換爲php代碼:<?php echo trim($val,'%');?> 那麼$exprArgs是什麼呢?它是一個數組,保存了每一個參數的類型、原義字符串、所屬腳本等等,通常用不到,不過特殊狀況下可能使用,好比內置的 default過濾器,在 default('') 指定參數的時候,返回的是 empty($var)?'':$var 這裏就須要從$exprArgs獲得每一個參數的信息。佈局

自定義模板函數也是一樣的原理,目的都是將標籤轉換爲php代碼,並保存到模板緩存中。性能

感言: 模板引擎並不神祕,只要理解其工做機制,代碼實現原理,每一個人都能實現本身的模板引擎。

相關文章
相關標籤/搜索