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

PHP 檔案式變數快取類:支援序列化與 var_export 兩種模式、自動過期與目錄管理

     編輯:PHP 綜合知識

Cache 類別完整代碼

<?php
class Cache {
    public $config = array(
        'cacheRoot' => './cache/',  // 快取根目錄,結尾需加 /
        'cacheTime' => 1,           // 快取秒數,0=不快取,負數=永久
        'cacheType' => 2,           // 1=serialize,2=var_export
        'cacheExe'  => '.php'       // 快取檔副檔名
    );
    private $return_name = array();

    public function __construct($cache_set = array()) {
        if (!empty($cache_set)) $this->config = array_merge($this->config, $cache_set);
        $this->config['ClassName'] = __CLASS__;
    }

    // 清除快取
    public function clear($filename = '') {
        if (empty($filename)) {
            $this->clear_dir($this->config['cacheRoot']);
        } elseif (file_exists($this->cache_file($filename))) {
            @unlink($this->cache_file($filename));
        } else {
            $this->clear_dir($this->config['cacheRoot'] . $filename);
        }
    }

    private function clear_dir($dir, $to = false) {
        if ($list = glob($dir . '/*')) {
            foreach ($list as $file) {
                is_dir($file) ? $this->clear_dir($file) : unlink($file);
            }
        }
        if ($to === false) @rmdir($dir);
    }

    // 寫入快取檔
    private function cache_write($filename, $text, $mode = 'w') {
        if (!file_exists($filename)) $this->makeDir(dirname($filename));
        if ($fp = @fopen($filename, $mode)) {
            flock($fp, LOCK_EX);
            fwrite($fp, $text);
            fclose($fp);
            return true;
        }
        return false;
    }

    // 檢查快取是否有效
    public function cache_is($fileName) {
        $fileName = $this->cache_file($fileName);
        if (!file_exists($fileName)) return false;
        if ($this->config['cacheTime'] < 0) return true;  // 永久
        if ($this->config['cacheTime'] == 0) return false; // 不快取
        $ctime = filemtime($fileName);
        return (time() - $ctime <= $this->config['cacheTime']);
    }

    // 存入資料並返回原資料
    public function cache_data($name, $data) {
        $varname = $name;
        $name = $this->cache_file($name);
        if ($this->config['cacheTime'] != 0) {
            if ($this->config['cacheType'] == 1) {
                $write_data = "<?php exit;?>" . serialize($data);
            } else {
                $write_data = "<?php\r\n\$var = " . var_export($data, true) . ";\r\n?>";
            }
            $this->cache_write($name, $write_data);
        }
        return $data;
    }

    // 讀取快取
    public function cache_read($file) {
        $file = $this->cache_file($file);
        if (!file_exists($file)) return '';
        if ($this->config['cacheType'] == 1) {
            $content = file_get_contents($file);
            $content = substr($content, 13); // 移除 
            return unserialize($content);
        } else {
            include_once($file);
            return $var;
        }
    }

    private function cache_file($filename) {
        return $this->config['cacheRoot'] . $filename . $this->config['cacheExe'];
    }

    // 遞歸建立目錄
    private function makeDir($dir, $mode = 0777) {
        $dir = str_replace('\\', '/', $dir);
        $mdir = '';
        foreach (explode('/', $dir) as $val) {
            $mdir .= $val . '/';
            if ($val == '..' || $val == '.' || $val == '') continue;
            if (!file_exists($mdir)) @mkdir($mdir, $mode);
        }
        return true;
    }
}

使用範例

$cache = new Cache(array('cacheTime' => 300, 'cacheType' => 2)); // 5 分鐘快取,var_export 模式

if ($cache->cache_is('user_list')) {
    $users = $cache->cache_read('user_list');
} else {
    $users = getUsersFromDB(); // 耗時操作
    $cache->cache_data('user_list', $users);
}

兩種儲存模式差異

模式cacheType優點缺點
序列化1支援所有資料型別、物件、資源較大、需 unserialize 解析
var_export2輸出合法 PHP 代碼、include 直接執行、可讀性高不支援資源型別、遞歸參考會截斷

安全性設計

  • 快取檔開頭 <?php exit;?> 防止直接訪問洩露資料
  • flock(LOCK_EX) 防止併發寫入衝突
  • 目錄可寫權限控制(建議 0755)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved