專案中常需快取資料庫查詢結果、API 回應等資料以提升效能。本文提供一個輕量、無相依的 PHP 檔案快取類 Cache,支援設定快取目錄、讀寫含過期判斷、自動建立多層目錄、清空快取等功能,適合中小型專案直接引入使用。
<?php
class Cache {
private $dir = 'data/cache/'; // 快取根目錄
private $key = 'c_a_sss'; // 檔名雜湊金鑰
/** 設定快取目錄並自動建立 */
public function set_dir($dirpath) {
$this->dir = $dirpath;
$this->make_dir($this->dir);
}
/** 讀取快取,若過期或不存在回傳 false */
public function read($key, $minutes = 1) {
$filename = $this->get_filename($key);
if ($datas = @file_get_contents($filename)) {
$datas = unserialize($datas);
if (time() - $datas['time'] < $minutes * 60) {
return $datas['data'];
}
}
return false;
}
/** 寫入快取(序列化 + 檔案鎖定) */
public function write($key, $data) {
$filename = $this->get_filename($key);
if ($handle = fopen($filename, 'w+')) {
$datas = ['data' => $data, 'time' => time()];
flock($handle, LOCK_EX);
$rs = fwrite($handle, serialize($datas));
flock($handle, LOCK_UN);
fclose($handle);
return $rs !== false;
}
return false;
}
/** 清空所有快取檔案 */
public function clear_all() {
$this->del_file($this->dir);
}
/** 產生唯一檔名:key_md5(key+secret) */
private function get_filename($key) {
return $this->dir . $key . '_' . md5($key . $this->key);
}
/** 遞迴建立多層目錄 */
private function make_dir($path) {
if (!file_exists($path)) {
$this->make_dir(dirname($path));
if (!mkdir($path, 0777)) {
die('無法建立快取資料夾: ' . $path);
}
}
}
/** 遞迴刪除目錄下所有檔案 */
private function del_file($dir) {
if (is_dir($dir)) {
$dh = opendir($dir);
while (false !== ($file = readdir($dh))) {
if ($file != '.' && $file != '..') {
$fullpath = $dir . '/' . $file;
if (!is_dir($fullpath)) {
unlink($fullpath);
} else {
$this->del_file($fullpath);
}
}
}
closedir($dh);
}
}
}
?>
<?php
require 'Cache.php';
$cache = new Cache();
$cache->set_dir('data/cache_dir/'); // 自訂目錄
// 嘗試讀取 1 分鐘內的快取
$data = $cache->read('sys', 1);
if (empty($data)) {
// 快取未命中:重新產生資料
$data = [
'aa' => 1111,
'bb' => 2222,
'date' => date('Y-m-d H:i:s')
];
$cache->write('sys', $data);
echo '資料來自資料庫/運算,已寫入快取
';
} else {
echo '資料來自快取
';
}
print_r($data);
?>
flock(LOCK_EX) 防止併發寫入損壞資料。unserialize 還原。$minutes 參數決定是否有效。make_dir 遞迴建立,免去手動部署步驟。md5(key + secret) 避免 key 衝突與路徑遍歷風險。memcached/Redis 驅動介面,統一 CacheInterface,依環境切換後端。clear_by_tag('user_1'))。這個類別雖簡單,但涵蓋檔案快取核心需求,直接複製即可用於 Laravel、CodeIgniter、原生 PHP 等專案。