首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

自製迷你 Smarty 模板引擎 MinSmarty:核心原理與完整實作

     編輯:PHP 綜合知識

Smarty 是 PHP 經典模板引擎,核心機制是「模板編譯為 PHP 快取檔」。本文從零實作一個極簡版 MinSmarty,展示模板讀取、正則替換變數標籤、編譯快取、引入執行的完整流程,適合理解模板引擎底層原理或輕量專案直接使用。

一、模板引擎核心優勢

  • 邏輯與視圖分離:PHP 只負責資料邏輯,HTML 只負責呈現。
  • 團隊協作友善:後端改邏輯不動模板,前端改樣式不動 PHP。
  • 編譯快取機制:首次編譯後直接執行 PHP,效能接近原生。

二、MinSmarty 類別完整代碼

<?php
class MinSmarty {
    // 模板目錄
    public $template_dir = "./templates/";
    // 編譯快取目錄
    public $compile_dir  = "./templates_c/";
    // 模板變數容器
    protected $tpl_vars = [];

    // 變數賦值
    public function assign($tpl_var, $value = null) {
        if ($tpl_var !== null) {
            $this->tpl_vars[$tpl_var] = $value;
        }
    }

    // 顯示模板(核心流程)
    public function display($tpl_file) {
        $tpl_path    = $this->template_dir . $tpl_file;
        $compile_path = $this->compile_dir . "com_" . $tpl_file . ".php";

        if (!file_exists($tpl_path)) {
            return false;
        }

        // 檢查是否需要重新編譯
        if (!file_exists($compile_path) || filemtime($tpl_path) > filemtime($compile_path)) {
            $content = file_get_contents($tpl_path);

            // 核心正則:{$var} => tpl_vars['var']; ?>
            $pattern = '/\{\s*\$([a-zA-Z_][a-zA-Z0-9_]*)\s*\}/i';
            $replace = '<?php echo $this->tpl_vars["${1}"]; ?>';
            $compiled = preg_replace($pattern, $replace, $content);

            file_put_contents($compile_path, $compiled);
        }

        // 直接引入編譯後的 PHP 檔案執行
        include_once($compile_path);
    }
}

三、使用範例

1. 控制器邏輯 intro.php

<?php
require_once "MinSmarty.class.php";

$title   = "這裡是標題";
$content = "這裡是內容 111111";

$smarty = new MinSmarty();
$smarty->assign("title", $title);
$smarty->assign("content", $content);
$smarty->display("intro.tpl");

2. 模板檔 templates/intro.tpl

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>{$title}</title>
</head>
<body>
    {$content}
</body>
</html>

3. 編譯後產生 templates_c/com_intro.tpl.php

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title><?php echo $this->tpl_vars["title"]; ?></title>
</head>
<body>
    <?php echo $this->tpl_vars["content"]; ?>
</body>
</html>

四、核心機制解析

  1. 變數標籤語法:{$variable},正則 /\{\s*\$([a-zA-Z_][a-zA-Z0-9_]*)\s*\}/i 支援大小寫、底線、數字。
  2. 編譯快取判斷:比較模板與快取檔 filemtime(),模板較新才重編譯。
  3. 執行上下文:include_once 在 display() 作用域執行,$this 指向 MinSmarty 實例,故能存取 $this->tpl_vars。
  4. 安全性:僅輸出經 assign() 設定的變數,避免任意變數洩漏。

五、擴展方向(留作練習)

  • 區塊標籤:{if}...{/if}, {foreach}...{/foreach} 需編譯為 PHP 流程控制結構。
  • 修飾器:{$var|escape:'html'} 對應 htmlspecialchars()。
  • 模板繼承:{extends 'layout.tpl'} + {block name} 實現佈局復用。
  • 快取機制:{cache lifetime=300} 輸出 HTML 直接快取。
  • 插件系統:自訂函數/修飾器註冊介面。

六、線上工具推薦

小結

MinSmarty 雖簡陋,卻完整展示了「模板→編譯→快取→執行」的核心生命週期。理解此原理,不僅能自製輕量模板引擎,更能深入掌握 Smarty、Twig、Blade 等主流引擎的設計哲學,遇到編譯異常、快取失效等問題時也能快速定位根因。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved