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

自製 PHP 模板類 pfcTemplate:高效、多級區塊、多來源支援詳解

     編輯:PHP 相關知識

前言

針對現有模板引擎過於笨重、學習曲線陡峭的問題,作者開發了輕量級 pfcTemplate 類,特點:無正則解析(純字串函數)、多級區塊嵌套、支援字串/文件/資料庫多來源、標識符可定制。本文詳細講解其核心設計、API 用法與實現原理。

核心特性

特性說明
高效解析使用 strpos、substr、str_replace 等字串函數,避免正則開銷
易用 API實例化 → 添加來源 → 設置變量/區塊 → 解析區塊 → 輸出
多級區塊支援無限層級嵌套(...)
多來源文件、字串變量、資料庫 BLOB、緩存鍵值
可定制標識符變量 {VAR}、區塊 可自定義格式

類結構與核心方法

<?php
class pfcTemplate {
    // 模板來源存儲 [handle => content]
    private array $templates = [];
    // 區塊存儲 [handle => [block_name => content]]
    private array $blocks = [];
    // 變量存儲 [handle => [var_name => value]]
    private array $vars = [];
    // 標識符配置
    public string $varOpen = '{';
    public string $varClose = '}';
    public string $blockOpen = '';
    public string $blockEndOpen = '';

    // 添加文件模板
    public function addFile(string $handle, string $filepath): bool {}
    // 添加字串模板
    public function setString(string $handle, string $content): void {}
    // 設置變量
    public function setVar(string $handle, string $name, $value): void {}
    public function setVars(string $handle, array $vars): void {}
    // 提取區塊
    public function setBlock(string $handle, string $blockName, string $blockHandle): bool {}
    // 解析區塊 (追加模式)
    public function parse(string $blockHandle, string $sourceBlock, bool $append = false): void {}
    // 解析並輸出
    public function parseOut(string $handle): string {}
    // 直接輸出
    public function fastPrint(string $handle): void {}
}
?>

使用流程範例

1. 模板字串 (或文件)

$tplStr = '
<html>
<body>
<h1>{TITLE}</h1>
<!-- BEGIN USER_ROW -->
<div>{NAME} - {EMAIL}</div>
<!-- END USER_ROW -->
</body>
</html>';

2. 實例化與設置

<?php
require 'pfcTemplate.php';

$tpl = new pfcTemplate();
// 可選:自定義標識符
// $tpl->varOpen = '{{';
// $tpl->varClose = '}}';

$tpl->setString('page', $tplStr);
$tpl->setVar('page', 'TITLE', '用戶列表');

// 提取區塊
$tpl->setBlock('page', 'USER_ROW', 'user_row');

3. 循環解析區塊

$users = [
    ['name' => 'Alice', 'email' => 'alice@example.com'],
    ['name' => 'Bob', 'email' => 'bob@example.com'],
];

foreach ($users as $user) {
    $tpl->setVars('user_row', $user);
    // 第三參數 true = 追加模式
    $tpl->parse('user_row', 'USER_ROW', true);
}

4. 輸出

$tpl->fastPrint('page'); // 直接 echo
// 或
$html = $tpl->parseOut('page'); // 獲取字串
echo $html;
?>

多級區塊嵌套實現原理

模板:

<!-- BEGIN OUTER -->
  外層: {OUTER_VAR}
  <!-- BEGIN INNER -->
    內層: {INNER_VAR}
  <!-- END INNER -->
<!-- END OUTER -->

解析順序:

  1. setBlock('page', 'OUTER', 'outer_handle') 提取外層區塊,父模板替換為 {outer_handle}。
  2. setBlock('outer_handle', 'INNER', 'inner_handle') 在外層區塊內提取內層。
  3. 循環內層數據:parse('inner_handle', 'INNER', true)。
  4. 循環外層數據:parse('outer_handle', 'OUTER', true),此時內層已展開。

內部解析邏輯 (簡化版)

private function parseBlock(string $targetHandle, string $sourceBlock, bool $append) {
    $blockContent = $this->blocks[$targetHandle][$sourceBlock] ?? '';
    $vars = $this->vars[$targetHandle] ?? [];
    
    // 替換變量
    foreach ($vars as $name => $value) {
        $placeholder = $this->varOpen . $name . $this->varClose;
        $blockContent = str_replace($placeholder, $value, $blockContent);
    }
    
    // 替換子區塊佔位符 (已在子 parse 時生成)
    // 子區塊解析後會在 $this->vars[$targetHandle] 生成對應佔位符鍵值
    
    if ($append) {
        $this->vars[$targetHandle][$sourceBlock] = 
            ($this->vars[$targetHandle][$sourceBlock] ?? '') . $blockContent;
    } else {
        $this->vars[$targetHandle][$sourceBlock] = $blockContent;
    }
}

進階:資料庫模板來源

<?php
// 從資料庫讀取模板字串
$stmt = $pdo->query("SELECT content FROM templates WHERE name = 'email_welcome'");
$templateStr = $stmt->fetchColumn();

$tpl->setString('email', $templateStr);
$tpl->setVar('email', 'USERNAME', $user->name);
$tpl->fastPrint('email');
?>

效能對比

引擎解析方式10000 次渲染記憶體學習成本
pfcTemplate字串函數~0.15s低極低
Smarty 3編譯 PHP~0.30s中中
Twig 3編譯 PHP~0.25s中中
原生 PHP include無~0.05s最低無

總結

pfcTemplate 以零依賴、零正則、API 極簡為優勢,適合:輕量專案、不想引入 Composer、模板邏輯簡單(變量替換+區塊循環)、需從資料庫讀取模板的場景。但缺乏自動逃逸、沙箱、繼承、插件機制,複雜專案建議使用 Twig/Blade。理解其「字串提取區塊→變量替換→追加合併」的核心流程,可自行擴展或參考設計輕量模板系統。

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