Smarty 模板引擎內建強大的快取機制,能大幅降低伺服器負載、提升回應速度。本文將系統介紹全域快取、區塊快取、區域快取三種模式的原理、設定步驟、程式碼範例與避坑指南。
// 啟用快取
$smarty->caching = true; // 或 1
// 快取目錄(需可寫入)
$smarty->cache_dir = './cache/';
// 快取壽命(秒),-1 為永不過期
$smarty->cache_lifetime = 3600;
內容較靜態、不依賴使用者狀態的頁面(如首頁、文章列表、靜態內容頁)。
同一模板若對應多種 URL 參數(如 ?cat=1、?cat=2),預設快取檔名相同會導致內容錯誤。解法:以 REQUEST_URI 產生唯一快取 ID。
$cacheId = md5($_SERVER['REQUEST_URI']); // 含查詢字串
$smarty->display('list.tpl', $cacheId);
Smarty 以 模板名 + 快取 ID 命名快取檔。不同 $cacheId 產生不同快取檔,實現「同模板、多內容」快取。
區塊快取的本質是「區塊不快取」:預設全開快取,再針對特定頁面呼叫 clear_cache() 禁用快取。
// 1.php、2.php 需要快取
$smarty->display('page.tpl', $cacheId); // 正常顯示,會產生快取
// 3.php 不需要快取(如即時儀表板)
$smarty->clear_cache('page.tpl', $cacheId); // 清除/禁用此模板+ID 的快取
$smarty->display('page.tpl'); // 第二參數留空,不產生新快取
clear_cache() 的模板名、快取 ID 必須與 display() 完全一致。clear_cache()。區域快取的本質是「區域不快取」:整頁快取,但透過 {insert} 標籤標記特定區塊為「動態區塊」,每次請求即時執行。
PHP
$smarty->assign('staticContent', '這段會被快取');
$smarty->display('page.tpl');
page.tpl
{$staticContent}
// 以下區塊不受快取影響,每次重新執行
{insert name='realtime'}
PHP 定義 insert 函式
function insert_realtime() {
return date('Y-m-d H:i:s'); // 即時時間
}
{insert name='xxx'}。insert_xxx() 函式並執行。insert_ + name 屬性值。$smarty->cache_modified_check = true; // 檢查來源檔案是否變動
$smarty->clear_cache('page.tpl', $cacheId, 'group_name'); // 按群組清除
| 坑點 | 原因 | 解法 |
|---|---|---|
| 參數不同卻顯示同內容 | 未使用動態 $cacheId | 用 md5(REQUEST_URI) 或關鍵參數組合 |
| 資料更新後前端未同步 | 快取未過期、未主動清除 | 資料異動後呼叫 clear_cache() 或縮短 cache_lifetime |
| {insert} 不生效 | 函式命名錯誤、未定義在 PHP 端 | 確認 insert_前綴、函式存在、回傳字串 |
| 快取目錄權限錯誤 | cache_dir 不可寫 | chmod 777 或指定 www-data 可寫目錄 |
| 模式 | 適用場景 | 複雜度 | 效能增益 |
|---|---|---|---|
| 全域快取 | 靜態頁、列表頁、SEO 頁 | 低 | 最高(整頁靜態化) |
| 區塊快取 | 大部分頁快取、少數頁即時 | 中 | 高 |
| 區域快取 | 單頁大部份靜態、小區塊動態(如用戶名、購物車數量、即時股價) | 中高 | 中高(平衡靜態與動態) |
Smarty 快取三部曲核心口訣:
clear_cache() 禁用特定頁{insert} 標記動態區塊善用三種模式組合,能在維持開發彈性的前提下,將頁面回應時間從百毫秒壓縮至幾毫秒,是高流量 PHP 專案的必備優化技能。