輕量級文件緩存類,支援全頁緩存、局部緩存、自動過期、手動清除、目錄自動創建、URL 綁定緩存文件。
<?php
class Cache {
private $dir; // 緩存目錄
private $lifetime; // 生存秒數
private $cacheid; // 緩存文件完整路徑
private $ext = '.php'; // 後綴
public function __construct($dir = '', $lifetime = 1800) {
if ($this->dirIsValid($dir)) {
$this->dir = rtrim($dir, '/') . '/';
$this->lifetime = $lifetime;
$this->cacheid = $this->getCacheId();
}
}
// 檢查緩存是否有效 (存在且未過期)
private function isValid(): bool {
if (!file_exists($this->cacheid)) return false;
$mtime = @filemtime($this->cacheid);
if (!$mtime) return false;
return (time() - $mtime) < $this->lifetime;
}
// 寫入緩存
public function write($mode = 0, $content = ''): bool {
switch ($mode) {
case 0: // 瀏覽器輸出緩存 (ob_get_contents)
$content = ob_get_contents();
break;
case 1: // 直接傳入內容
break;
case 2: // 讀取本地文件 (較少用)
$content = file_get_contents($content);
break;
}
ob_end_flush(); // 發送給瀏覽器並關閉輸出緩存
try {
// 確保目錄存在
if (!is_dir(dirname($this->cacheid))) {
mkdir(dirname($this->cacheid), 0755, true);
}
return file_put_contents($this->cacheid, $content) !== false;
} catch (Exception $e) {
error_log('Cache write failed: ' . $e->getMessage());
return false;
}
}
// 載入緩存 (有效則直接輸出並 exit)
public function load(): void {
if ($this->isValid()) {
// 方式一:require 解析 PHP 代碼 (緩存文件含 PHP 標簽)
require_once $this->cacheid;
// 方式二:直接輸出內容 (純 HTML)
// echo file_get_contents($this->cacheid);
echo '';
exit;
} else {
ob_start(); // 開啟輸出緩存,準備寫入
}
}
// 清除緩存
public function clean(): bool {
if (file_exists($this->cacheid)) {
return @unlink($this->cacheid);
}
return true;
}
// 生成緩存文件名:MD5(URL)
private function getCacheId(): string {
return $this->dir . md5($this->getCurrentUrl()) . $this->ext;
}
// 獲取當前完整 URL
private function getCurrentUrl(): string {
$url = '';
if (isset($_SERVER['REQUEST_URI'])) {
$url = $_SERVER['REQUEST_URI'];
} else {
$url = $_SERVER['PHP_SELF'];
$url .= empty($_SERVER['QUERY_STRING']) ? '' : '?' . $_SERVER['QUERY_STRING'];
}
return $url;
}
// 檢查/創建目錄
private function dirIsValid($dir): bool {
if (is_dir($dir)) return true;
try {
return mkdir($dir, 0755, true);
} catch (Exception $e) {
error_log('Cache dir create failed: ' . $e->getMessage());
return false;
}
}
}
?>
<?php
// 頁面最頂部
$cachedir = __DIR__ . '/cache/';
$cache = new Cache($cachedir, 300); // 5 分鐘
// 強制刷新:?cacheact=rewrite 或 ?clearCache=ok
if (($_GET['cacheact'] ?? '') !== 'rewrite' && ($_GET['clearCache'] ?? '') !== 'ok') {
$cache->load(); // 緩存有效則直接輸出並 exit
}
// --- 以下為動態業務邏輯 ---
// 數據庫查詢、模板渲染、複雜計算...
echo "動態生成內容: " . date('H:i:s');
// 頁面底部
$cache->write(); // 首次或過期時寫入緩存
?>
<?php
function getHotArticles($limit = 10) {
$cache = new Cache(__DIR__ . '/cache/data/', 600);
$key = 'hot_articles_' . $limit;
$cache->cacheid = $cache->dir . md5($key) . $cache->ext; // 手動指定 key
if ($cache->isValid()) {
return require $cache->cacheid; // 緩存文件返回數組
}
// 耗時查詢
$data = $db->query("SELECT * FROM articles ORDER BY views DESC LIMIT $limit")->fetchAll();
// 寫入緩存 (返回 PHP 數組代碼)
$content = "";
file_put_contents($cache->cacheid, $content);
return $data;
}
?>
<?php return array (
0 => array ('id' => 1, 'title' => 'PHP技巧', 'views' => 1024),
1 => array ('id' => 2, 'title' => 'MySQL優化', 'views' => 896),
); ?>
<?php
// 1. 緩存標籤/分組清除
class TaggedCache extends Cache {
private $tags = [];
public function setTags(array $tags) { $this->tags = $tags; }
public function cleanByTag($tag) {
// 掃描目錄,解析文件頭註釋標籤,匹配則刪除
}
}
// 2. 多級緩存:內存 (APCu/Redis) + 文件
class MultiLevelCache {
public function get($key) {
if ($data = apcu_fetch($key)) return $data;
// 降級到文件...
}
public function set($key, $data, $ttl) {
apcu_store($key, $data, $ttl);
// 同步文件...
}
}
// 3. 緩存預熱 CLI 命令
// php cli.php cache:warm /article/list /product/detail
?>
文件緩存類構建簡單、無外部依賴、適合中小項目快速引入。核心邏輯:URL 綁定文件名、修改時間判斷過期、輸出緩存捕獲內容。生產環境建議配合 OPcache、Redis 多級緩存架構,並建立完善的緩存更新/清除策略。