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

Smarty 緩存機制全解析:全局、部分、局部緩存與清除策略

     編輯:PHP 相關知識

一、啟用緩存基礎配置

<?php
require 'Smarty.class.php';
$smarty = new Smarty();

$smarty->caching = true;                    // 啟用緩存
$smarty->cache_dir = './cache/';            // 緩存目錄(需可寫)
$smarty->cache_lifetime = 3600;             // 生存時間(秒),-1 永不過期
$smarty->compile_check = false;             // 生產環境關閉編譯檢查提升性能
?>

二、緩存 ID (cache_id) 實現多版本緩存

同一模板根據不同條件(用戶、參數、語言)生成獨立緩存。

<?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+
?>

四、全局緩存:整站頁面緩存

適用於內容較靜態、流量大的頁面(首頁、列表頁、詳情頁)。

實現要點

  1. 入口文件統一啟用緩存配置
  2. 每個控制器 display() 時傳入唯一 cache_id
  3. cache_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} 動態區塊

頁面整體緩存,但某些區塊(用戶信息、購物車數量、廣告位、時間)需實時更新。

原理

  1. 定義 insert_() 函數(注意下劃線)
  2. 模板中用 {insert name=""} 調用
  3. 緩存時 不緩存 insert 區塊,每次請求實時執行

完整示例

<?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 進階:傳參

{* 模板 *}
{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分佈式部署、高可用架構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved