Skip to content

Instantly share code, notes, and snippets.

@imdong
Created November 16, 2017 07:11
Show Gist options
  • Save imdong/f8d655ff56cb1313d6a56fbbc996e44f to your computer and use it in GitHub Desktop.
Save imdong/f8d655ff56cb1313d6a56fbbc996e44f to your computer and use it in GitHub Desktop.
简易文件缓存系统
<?php
/**
* 文件缓存系统
*
* 普通Cache缓存类,适用于大量零碎小数据缓存。大文件缓存不适用。
*
* 特点:缓存文件分目录储存,防止单个目录下文件过多导致IO效率变低。
* 可以控制子目录数,文件数始终在一个可以预见的数量范围之内。
*
* 说明:
* @author 青石 <[email protected]> http://www.qs5.org
* @version 0.1 完成于 2015/6/8
*
*/
class Cache {
// 定义类默认设置
static $Config = array(
'Cache_Dir' => './Cache', // 默认保存目录
'File_Life' => 86400, // 默认缓存有效时间 24小时 单位(s)
'File_Suffix' => '.Cache.php',// 默认缓存文件名后缀 建议使用 .php 结尾
'Group_Dir_Size' => -3, // 文件夹分组命名字符节数 必须使用负数 设置为0则不分子文件夹
'Group_File_Size' => 4, // 文件名字命名字符节数 目录下文件数会限制在 16的N次方
'Group_Dir_Depr' => '_', // 分类多级目录替换符 为空则不分级
);
// 保存缓存信息
static public function save($Name, $Data, $Time = 0){
if(strlen($Name) < 1) return false;
$path = self::_getPathName($Name);
if(!self::_mkDir($path['dir'])){
die('<b>Error</b>: Create a cache directory fails, check whether write permission.');
}
$Time = (($Time == 0) ? self::$Config['File_Life'] : $Time) + time();
if(is_file($path['path'])){
$file_str = file_get_contents($path['path']);
$file_str = substr($file_str, 14);
$file_info = unserialize($file_str);
}
$file_info[$path['hash']] = array('n' => $Name, 't' => $Time, 'd' => $Data);
$file_text = "<?php exit; ?>" . serialize($file_info);
if(!file_put_contents($path['path'], $file_text, LOCK_EX)){
return false;
}
return true;
}
// 读取缓存信息
static public function read($Name){
if(strlen($Name) < 1) return false;
$path = self::_getPathName($Name);
if(!is_file($path['path'])){
return NULL;
}
$file_info = file_get_contents($path['path']);
$file_info = substr($file_info, 14);
$ret_info = unserialize($file_info);
$ret_info = $ret_info[$path['hash']];
if($ret_info['t'] < time()){
self::del($Name);
return NULL;
}
return $ret_info['d'];
}
// 删除缓存信息
static public function del($Name){
if(strlen($Name) < 1) return false;
$path = self::_getPathName($Name);
if(!is_file($path['path'])){
return true;
}
$file_info = file_get_contents($path['path']);
$file_info = substr($file_info, 14);
$ret_info = unserialize($file_info);
unset($ret_info[$path['hash']]);
// 保存信息
$file_text = "<?php exit; ?>" . serialize($ret_info);
if(!file_put_contents($path['path'], $file_text, LOCK_EX)){
return false;
}
return true;
}
// 私有方法 循环创建目录
static private function _mkDir($dir, $mode = 0777){
if(is_dir($dir)){
return true;
}else if(!is_dir(dirname($dir)) && !self::_mkDir(dirname($dir), $mode)){
return false;
}
return mkdir($dir, $mode);
}
// 私有方法 获取文件目录与关键字信息
static private function _getPathName($Name){
$path = explode('/', $Name); // 分解名称
if(count($path)<=1){
$path = array('', $path['0']);
}else{
$path['0'] = str_replace(self::$Config['Group_Dir_Depr'], '/', $path['0']) . '/';
}
$ret_path['hash'] = md5(strtolower($Name));
$ret_path['dir'] = self::$Config['Cache_Dir'] . '/' . $path['0'] . (self::$Config['Group_Dir_Size'] < 0 ? substr($ret_path['hash'], self::$Config['Group_Dir_Size']) . '/' : '');
$ret_path['name'] = substr($ret_path['hash'], 0, self::$Config['Group_File_Size']) . self::$Config['File_Suffix'];
$ret_path['path'] = $ret_path['dir'] . $ret_path['name'];
return $ret_path;
}
}
// 封装成快捷调用方法 S(); 可根据需要更改方法名
function Cae($Name, $Data = '', $time = 0){
if(strlen($Name) < 1) return false;
if($Data == ''){
return Cache::read($Name);
}elseif($Data == NULL){
return Cache::del($Name);
}else{
return Cache::save($Name, $Data, $time);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment