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

PHP 簡易檔案快取類實作:支援過期時間、序列化儲存與目錄自動建立

     編輯:PHP 綜合知識

專案中常需快取資料庫查詢結果、API 回應等資料以提升效能。本文提供一個輕量、無相依的 PHP 檔案快取類 Cache,支援設定快取目錄、讀寫含過期判斷、自動建立多層目錄、清空快取等功能,適合中小型專案直接引入使用。

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'))。
  • 加入快取命中率統計、記憶體快取(APCu)混合模式。

這個類別雖簡單,但涵蓋檔案快取核心需求,直接複製即可用於 Laravel、CodeIgniter、原生 PHP 等專案。

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