無需引入 Redis/Memcached,利用文件系統實現頁面級緩存,適合中小流量站點。核心機制:Head.php 檢查緩存文件是否存在且未過期 → 直接輸出並 exit;否則啟用 ob_start() 捕獲輸出。Foot.php 在腳本結束時將緩存寫入文件。另含「雙擊強制刷新」邏輯。
<?php
define('CACHE_EXPIRE', 1800); // 30 分鐘過期
define('CACHE_PATH', $_SERVER['DOCUMENT_ROOT'] . '/cache/');
define('REFRESH_EXPIRE', 10); // 10 秒內連續刷新視為強制刷新
is_dir(CACHE_PATH) || mkdir(CACHE_PATH, 0777, true);
// 判斷用戶是否在 REFRESH_EXPIRE 秒內連續請求同一 URL
function refreshTimes() {
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
if (isset($_COOKIE['refreshTimes'])) {
[$cookieUrl, $time, $count] = explode("\t", $_COOKIE['refreshTimes']);
if ($cookieUrl === $url && $_SERVER['REQUEST_TIME'] - $time < REFRESH_EXPIRE) {
setcookie('refreshTimes', "$url\t{$_SERVER['REQUEST_TIME']}\t" . ($count+1), 0, '/');
return (int)$count;
}
}
setcookie('refreshTimes', "$url\t{$_SERVER['REQUEST_TIME']}\t1", 0, '/');
return 0;
}
$key = md5($_SERVER['REQUEST_URI']);
$path = CACHE_PATH . $key;
// 命中緩存且非強制刷新
if (is_file($path) && filemtime($path) + CACHE_EXPIRE > $_SERVER['REQUEST_TIME'] && refreshTimes() === 0) {
readfile($path);
exit;
}
ob_start();
?>
<?php $html = ob_get_contents(); ob_end_clean(); file_put_contents($path, $html); echo $html; ?>
<?php include 'Head.php'; ?>
<!DOCTYPE html>
<html><head><title><?= $title ?? 'Demo' ?></title></head>
<body><?= "動態內容 " . date('H:i:s') ?></body></html>
<?php include 'Foot.php'; ?>
md5($uri . $role . $lang)。flock() 或遷移至 Redis。expires 指令,不經 PHP。CACHE_PATH 刪除過期文件。此方案代碼量極小,接入成本低,能立竿見影降低動態頁響應時間。