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

PHP 輕量級頁面緩存類:基於 URL 與文件修改時間的智能失效機制

     編輯:PHP 相關知識

類設計目標

提供一個開箱即用的全頁緩存方案,核心特性:

  • 按 $_SERVER['REQUEST_URI'] 自動區分緩存文件(支持動態參數如 test.php?id=12)
  • 可配置緩存過期時間(默認 120 秒)
  • 智能失效:當目標腳本文件(__FILE__)修改時間晚於緩存文件時,強制重新生成,解決代碼部署後緩存不更新的痛點
  • 輸出緩衝區(ob_start)捕獲頁面輸出,無需修改業務邏輯

核心代碼結構

class cache {
    var $cache_dir = './cache/';
    var $cache_time = 120;
    var $caching = false;
    var $file = '';

    function __construct() {
        $this->file = $this->cache_dir . urlencode($_SERVER['REQUEST_URI']);
        $expired = file_exists($this->file) ? $this->check_expire() : false;
        
        // 命中有效緩存:直接輸出並退出
        if (file_exists($this->file) 
            && (filemtime($this->file) + $this->cache_time) > time() 
            && !$expired) {
            $handle = fopen($this->file, 'r');
            while ($data = fread($handle, 8192)) echo $data;
            fclose($handle);
            exit();
        }
        // 未命中或已過期:啟用緩存模式
        $this->caching = true;
        ob_start();
        echo '<!--last modified:' . time() . '--> '; // 嵌入時間戳供失效檢測
    }

    function close() {
        if ($this->caching) {
            $data = ob_get_clean();
            echo $data;
            $fp = fopen($this->file, 'w');
            fwrite($fp, $data);
            fclose($fp);
        }
    }

    // 檢測源文件是否更新
    function check_expire() {
        $fp = fopen($this->file, 'r');
        preg_match('/:(\d+)-/', fread($fp, 200), $time);
        $modify_time = $time[1];
        fclose($fp);
        return $modify_time < filemtime($_SERVER['SCRIPT_FILENAME']);
    }
}

使用示例

<?php
require_once 'cache.class.php';
$ch = new cache(); // 構造函數自動檢測緩存,命中則直接輸出並 exit

// 業務邏輯:查詢數據庫、渲染模板等
echo date('D M j G:i:s T Y'); // 模擬動態內容

$ch->close(); // 緩存模式下將輸出寫入文件
?>

關鍵機制深度解析

機制實現細節作用
緩存鍵生成urlencode($_SERVER['REQUEST_URI'])不同 URL 參數生成獨立緩存文件,避免衝突
時間過期判斷filemtime($file) + $cache_time > time()基於文件修改時間的簡單 TTL 機制
源文件變更檢測正則提取緩存文件頭部時間戳,對比 filemtime(__FILE__)代碼部署後自動失效舊緩存,無需手動清理
輸出捕獲ob_start() / ob_get_clean()非侵入式攔截輸出,業務代碼無感知

局限性與改進建議

  • 併發競爭:高併發下多進程同時寫入同一緩存文件可能導致損壞。建議引入 flock() 文件鎖或改用 Redis。
  • 緩存雪崩:熱點頁面過期瞬間大量請求擊穿 DB。可採用「隨機過期時間」或「後台異步預熱」緩解。
  • 動態內容區分:同一 URL 不同用戶(如登錄態)見到不同內容。需在緩存鍵中加入用戶標識(Session ID、用戶 ID)。
  • 正則脆弱性:preg_match('/:(\d+)-/') 依賴特定註釋格式。建議改用 serialize()/json_encode() 存儲元數據(過期時間、源文件 mtime 等)。

總結

這個緩存類以極少代碼實現了「按 URL 區分、時間過期、源文件變更自動失效」三大核心功能,非常適合中小型項目快速接入頁面級緩存。理解其原理後,可根據業務規模演進至更健壯的緩存架構。

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