<?php
require 'Smarty.class.php';
$smarty = new Smarty();
$smarty->caching = true; // 啟用緩存
$smarty->cache_dir = './cache/'; // 緩存目錄(需可寫)
$smarty->cache_lifetime = 3600; // 生存時間(秒),-1 永不過期
$smarty->compile_check = false; // 生產環境關閉編譯檢查提升性能
?>
同一模板根據不同條件(用戶、參數、語言)生成獨立緩存。
<?php
// 根據請求 URI 生成唯一緩存 ID(包含查詢參數)
$cacheId = md5($_SERVER['REQUEST_URI']);
$smarty->display('index.tpl', $cacheId);
// 或根據用戶 ID + 頁面
$cacheId = 'user_' . $userId . '_page_' . $page;
$smarty->display('profile.tpl', $cacheId);
?>
關鍵點:display() 第二個參數即 cache_id。不同 ID 產生不同緩存文件,互不干擾。
<?php
// 1. 清除所有緩存
$smarty->clear_all_cache();
// 2. 清除指定模板所有緩存
$smarty->clear_cache('index.tpl');
// 3. 清除指定模板 + 指定 cache_id
$smarty->clear_cache('index.tpl', $cacheId);
// 4. 清除過期緩存(按 lifetime)
$smarty->clear_cache(null, null, null, time() - 3600); // Smarty 3.1+
?>
適用於內容較靜態、流量大的頁面(首頁、列表頁、詳情頁)。
display() 時傳入唯一 cache_idcache_id 推薦使用 md5($_SERVER['REQUEST_URI']),自動區分不同參數<?php
// ❌ 錯誤:同一模板無 cache_id,不同參數頁面共用一個緩存
$smarty->display('article.tpl'); // id=5 和 id=7 會顯示同一內容
// ✅ 正確:包含完整請求 URI
$smarty->display('article.tpl', md5($_SERVER['REQUEST_URI']));
// 或手動構造:'article_' . (int)$_GET['id']
?>
實質是「全局開啟,個別關閉」。在不需緩存的頁面執行 display() 前清除該模板緩存。
<?php
// article.php - 動態內容(評論、實時數據),不緩存
$smarty->clear_cache('article.tpl'); // 清除可能存在的舊緩存
$smarty->display('article.tpl'); // 不傳 cache_id,也不會生成新緩存(因 caching=true 但無 cache_id 仍會緩存?需注意)
// 更穩妥:臨時關閉緩存
$smarty->caching = false;
$smarty->display('article.tpl');
$smarty->caching = true; // 恢復
?>
注意:clear_cache() 參數必須與生成緩存時的 display() 參數完全一致(模板名、cache_id、compile_id)。
頁面整體緩存,但某些區塊(用戶信息、購物車數量、廣告位、時間)需實時更新。
insert_() 函數(注意下劃線){insert name=""} 調用<?php
// PHP 控制器
$smarty->assign('pageTitle', '文章詳情');
$smarty->assign('content', $articleContent);
$smarty->display('article.tpl', md5($_SERVER['REQUEST_URI']));
// 必須定義:insert_ + 自定義名
function insert_userPanel() {
if (isset($_SESSION['user'])) {
return '<span class="user">' . htmlspecialchars($_SESSION['user']['name']) . '</span>';
}
return '<a href="/login">登錄</a>';
}
function insert_currentTime() {
return date('Y-m-d H:i:s');
}
?>
{* article.tpl *}
<html>
<head><title>{$pageTitle}</title></head>
<body>
<header>
{insert name="userPanel"} {* 實時:用戶面板 *}
{insert name="currentTime"} {* 實時:當前時間 *}
</header>
<article>{$content}</article> {* 緩存:文章內容 *}
<aside>
{insert name="adSlot" slot="sidebar"} {* 實時:廣告位 *}
</aside>
</body>
</html>
{* 模板 *}
{insert name="adSlot" slot="sidebar" width=300}
{* PHP *}
function insert_adSlot(array $params) {
$slot = $params['slot'] ?? 'default';
$width = $params['width'] ?? 200;
// 查詢廣告邏輯...
return $adHtml;
}
將緩存存儲到 Redis、Memcached、資料庫等,實現分佈式緩存共享。
<?php
$smarty->cache_handler_func = 'myCacheHandler';
function myCacheHandler($action, &$smarty, &$cacheContent, $tplFile = null, $cacheId = null, $compileId = null) {
$key = 'smarty:' . $tplFile . ':' . $cacheId . ':' . $compileId;
switch ($action) {
case 'read':
$cacheContent = Redis::get($key);
return $cacheContent !== false;
case 'write':
return Redis::setex($key, $smarty->cache_lifetime, $cacheContent);
case 'clear':
return Redis::del($key);
default:
return false;
}
}
?>
| 模式 | 適用場景 | 實現方式 | 典型頁面 |
|---|---|---|---|
| 全局緩存 | 高流量、低動態內容 | 全站啟用 caching + REQUEST_URI cache_id | 首頁、列表頁、商品詳情 |
| 部分緩存 | 大部分頁面緩存,個別頁面動態 | 全局開啟 + 動態頁面 clear_cache 或 臨時關閉 caching | 用戶中心、實時數據大屏 |
| 局部緩存 | 頁面整體可緩存,小區塊動態 | {insert} 標籤 + insert_* 函數 | 用戶欄、購物車、廣告、時間 |
| 自定義處理器 | 多服務器集群、緩存共享 | cache_handler_func 指向 Redis/Memcached | 分佈式部署、高可用架構 |