PHP模板引擎的原理與實踐

jopen 10年前發布 | 39K 次閱讀 PHP模板引擎 模板引擎

0x00 模板引擎的原理

模板引擎就是在模板文件中使用一系列提前約定好的標簽代替原生PHP代碼,通過訪問一個PHP的入口文件,會有一個PHP編譯文件根據約定替換模板內標簽以及標簽內變量,最終將模板文件編譯成一個PHP文件,然后展示到瀏覽器中。

模板文件

前端開發者將前端代碼中的所有數據替換成與服務端開發者約定好的標簽及變量名。

PHP入口文件

服務端開發者將前端代碼中所需要的變量注入到前端。

PHP編譯文件

該文件中是模板引擎中的核心,在這里我們定義了標簽語句等,通過讀取模板文件,使用正則表達式去匹配模板文件中與后臺約定好的標簽及變量,并將標簽及變量替換成PHP代碼,最終生成一個前后端結合的PHP文件。

0x01 約定標簽

PHP的語法中,包括if...elseforeach等語法,以及需要替換的普通變量$value, PHP原生語句,注釋等等。一般情況下,大家習慣使用以下標簽

{$value}
// 對應原生
<?php echo $value; ?>
{foreach $array}
    {V}
{/foreach}
// 對應原生
<?php
foreach($array as $K => $V) {
    echo $V;
}
?>
{if $data == 'XiaoMing'}
    I'm XiaoMing;
{else if $data == 'XiaoHong' }
    I'm XiaoHong;
{else}
    I'm XiaoLi;
{/if}
// 對應原生
<?php
    if($data == 'XiaoMing') {
        echo "XiaoMing";
    } else if ($data == 'XiaoHong') {
        echo "XiaoHong";
    } else {
        echo "XiaoLi";
    }
?>

等等,這些大家可以參考SmartyDiscuz的標簽。

0x02 構造正則表達式匹配標簽及變量  <small>正則表達式30分鐘入門教程</small>

對于正則表達式,大家可以戳進上面的教程,簡單易用。
下面直接給出相關標簽的正則表達式。

// 匹配的正則表達式
$this->TP[] = "#{\$([a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff])}#";    // 匹配普通變量
$this->TP[] = "#{foreach \$([a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff])}#";     // 匹配{foreach $array}
$this->T_P[] = "#{\/(foreach|if)}#";    // 匹配{/foreach} or {/if}

// 對應的替換內容 $this->T_R[] = "<?php echo \$this->value['\1']; ?>"; $this->T_R[] = "<?php foreach((array)\$this->value['\1'] as \$K => \$V) { ?>"; $this->T_R[] = "<?php }?>";</pre>

0x03 對模板文件進行編譯

編譯就是對模板文件讀取,使用正則表達式對模板標簽及變量進行替換,最終將替換后的內容保存在一個PHP文件中即可。

使用的相關函數:

<?php
// 讀取文件內容
file_get_contents($file)

// 正則替換 preg_replace(pattern, replacement, subject); ?></pre>

0x04 結束并聲明

通過這三步,一個簡單的模板引擎就已經制作成功了,但是模板引擎的工作原理上面已經說過了,在進行正則匹配替換的過程中,效率極低,PHP自身效率本來就很低,在加上正則匹配,就可想而知了。所以,一般情況下,模板引擎都會有自己的緩存機制,將解析成功的內容保存成一個html文件,并設置緩存有效期,這樣可以很大程度上提升效率。

聲明

本文是學習《PHP核心技術與最佳實踐》列旭松 陳文著 第6章 PHP模板引擎的原理與實踐 學習筆記。
感謝作者!

原創文章,轉載時必須以超鏈接的形式注明作者和原始出處。 | 作者 : 我才是二亮

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!