將動態 PHP 頁面輸出內容快取到檔案系統,設定 TTL(存活時間)。同一 URL + 參數在 TTL 內再次請求,直接讀取快取檔輸出,完全繞過 PHP 邏輯與 MySQL 查詢。
<?php
require_once 'arrcache.php';
$cache = new ArrCache('cache', 120, 'txt'); // 目錄、秒數、副檔名
for ($i = 0; $i < 5; $i++) {
echo $i . ' ';
sleep(1); // 模擬耗時查詢
}
$cache->endCache(); // 必須放在腳本結尾
?>
首次執行 ~5 秒,第二次瞬間輸出。
<?php
ob_start(); // 開啟輸出緩衝
class ArrCache {
private $path, $time, $fileType, $fileName;
public function __construct($path, $time = 120, $fileType = 'txt') {
$this->path = $path;
$this->time = $time;
$this->fileType = $fileType;
// 以 URL + QUERY_STRING 為唯一鍵
$this->fileName = $_SERVER['DOCUMENT_ROOT'] . '/' . $this->path . '/' . md5($_SERVER['REQUEST_URI']) . '.' . $this->fileType;
// 快取命中:檔案存在且未過期
if (file_exists($this->fileName) && (filemtime($this->fileName) + $this->time > time())) {
readfile($this->fileName);
ob_end_flush();
exit; // 直接結束,不執行後續 PHP
}
}
public function endCache() {
$fp = fopen($this->fileName, 'w');
fwrite($fp, ob_get_contents()); // 寫入輸出緩衝內容
fclose($fp);
ob_end_flush();
}
}
?>
| 點 | 處理 |
|---|---|
| 快取鍵 | md5($_SERVER['REQUEST_URI']) 包含查詢字串,不同參數不同快取 |
| 過期判斷 | filemtime + ttl > time() |
| 輸出捕獲 | ob_start() + ob_get_contents() |
| 提前退出 | 建構子命中時 exit,節省所有後續運算 |
| 目錄權限 | 需預先建立 cache/ 並給 PHP 寫入權限 |
| ✅ 適合 | ❌ 不適合 |
|---|---|
| 內容頁、列表頁、報表、公開 API | 購物車、訂單、用戶中心(個人化強) |
| SELECT 為主、資料變動低 | INSERT/UPDATE/DELETE 頻繁頁面 |
| 高流量、低延遲要求 | 需即時性的儀表板、即時通訊 |
gzencode(ob_get_contents(), 9) 寫入,讀取時 gzinflate(),節省 70% 磁碟空間。stale-while-revalidate)。deny all)。極光快取類展示了 頁面級檔案快取 的最小可行實現:ob_start + md5(URL) + TTL + exit。生產環境建議直接使用成熟方案:Nginx fastcgi_cache / proxy_cache、Varnish、Redis 全頁快取、Laravel Response Cache、Symfony HttpCache,功能更完善(標籤失效、熱鍵保護、分散式、監控)。