輕量級靜態頁生成類別 `Shtml`,將資料陣列對應替換模板中的 `
<?php
class Shtml {
public $DataSource = []; // 資料來源陣列 [鍵 => 值]
public $Templet = ''; // 模板字串
public $FileName = ''; // 輸出檔案路徑
// 綁定資料
public function BindData(array $arr) {
$this->DataSource = $arr;
}
// 設定模板
public function setTemplate($template) {
$this->Templet = $template;
}
// 設定輸出檔案
public function setFileName($filename) {
$this->FileName = $filename;
}
// 生成靜態頁
public function Create() {
if (empty($this->Templet)) {
throw new Exception('模板未設定');
}
if (empty($this->FileName)) {
throw new Exception('輸出檔案未設定');
}
$tmp = $this->Templet;
// 替換所有標籤
foreach ($this->DataSource as $key => $value) {
$tag = '<FIELD_' . $key . '>';
$tmp = str_replace($tag, $value, $tmp);
}
// 確保目錄存在
$dir = dirname($this->FileName);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
// 寫入檔案
$result = file_put_contents($this->FileName, $tmp);
if ($result === false) {
throw new Exception("寫入檔案失敗: {$this->FileName}");
}
return $result; // 回傳寫入位元組數
}
}
?>
<?php
require 'Shtml.php';
$data = [
'title' => '最新文章標題',
'content' => '<p>這是文章內容,支援 HTML 標籤。</p>',
'author' => '張三',
'date' => date('Y-m-d H:i:s')
];
$template = '
<!DOCTYPE html>
<html>
<head>
<title><FIELD_title></title>
</head>
<body>
<h1><FIELD_title></h1>
<div class="meta">作者: <FIELD_author> | 日期: <FIELD_date></div>
<div class="content"><FIELD_content></div>
</body>
</html>
';
$generator = new Shtml();
$generator->BindData($data);
$generator->setTemplate($template);
$generator->setFileName('output/article_' . time() . '.html');
try {
$bytes = $generator->Create();
echo "靜態頁生成成功: {$generator->FileName} ({$bytes} bytes)";
} catch (Exception $e) {
echo "錯誤: " . $e->getMessage();
}
?>
// 擴展版:支援 ... 迴圈
class AdvancedShtml extends Shtml {
public function Create() {
$tmp = $this->Templet;
// 1. 處理迴圈區塊
if (preg_match_all('/<!-- BEGIN:(\w+) -->(.*?)<!-- END:\\1 -->/s', $tmp, $matches)) {
foreach ($matches[1] as $i => $blockName) {
$blockContent = $matches[2][$i];
$fullBlock = $matches[0][$i];
// 資料必須是陣列的陣列
if (isset($this->DataSource[$blockName]) && is_array($this->DataSource[$blockName])) {
$rendered = '';
foreach ($this->DataSource[$blockName] as $item) {
$itemHtml = $blockContent;
foreach ($item as $k => $v) {
$itemHtml = str_replace('<FIELD_' . $k . '>', $v, $itemHtml);
}
$rendered .= $itemHtml;
}
$tmp = str_replace($fullBlock, $rendered, $tmp);
} else {
$tmp = str_replace($fullBlock, '', $tmp); // 無資料則移除區塊
}
}
}
// 2. 處理條件區塊 ...
$tmp = preg_replace_callback('/<!-- IF:(\w+) -->(.*?)<!-- ENDIF:\\1 -->/s', function($m) {
return !empty($this->DataSource[$m[1]]) ? $m[2] : '';
}, $tmp);
// 3. 一般欄位替換
foreach ($this->DataSource as $key => $value) {
if (!is_array($value)) { // 跳過迴圈資料
$tmp = str_replace('<FIELD_' . $key . '>', $value, $tmp);
}
}
// 寫入檔案...
return file_put_contents($this->FileName, $tmp);
}
}
?>
| 優點 | 缺點 |
|---|---|
| 極簡單、無依賴、易理解 | 功能有限:無繼承、佈局、過濾器、快取 |
| 效能極高 (純字串替換) | 安全性:需自行過濾輸出防 XSS |
| 適合生成靜態檔案部署 CDN | 維護性差:邏輯與模板混雜 |
| 可擴展性強 (如上所示) | 大型專案難以管理 |
本類別適合極簡專案、靜態站點生成器、舊系統維護、學習模板引擎原理。新專案請直接使用成熟模板引擎。