项目搭建在 cache 目录下
- index.php 为入口文件
- Lib 目录为类库目录,Autoload.php 为自动加载类,用来实现类的自动加载。
- Cache 目录里面创建 Cache.php 基类,通过一个简单的工厂函数进行调用。
- Cache 目录里面创建 Interfaces 目录,通过接口的方式用来约束缓存的封装。File.php 里用来实现CacheInterface.php 定义的方法。
index.php
<?php
use Lib\Cache\Cache;
//定义根目录常量
define('ROOT', dirname(__FILE__));
require_once ROOT . DIRECTORY_SEPARATOR . '/Lib/AutoLoad.php';
$cache = Cache::Factory('file', ['pre_fix'=>'A.S.\//:DF', 'file_ext'=>'.cache']);
var_dump($cache->save('demo',json_encode(['code'=>1,'msg'=>'demo value']), 50));
var_dump($cache->get('demo'));
//var_dump($cache->flush());
Lib/AutoLoad.php
<?php
/*
自动加载类
*/
namespace Lib;
class AutoLoad{
public static function loadClass($className){
// 根据 className 获取类库地址
$class = ROOT . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
if(is_file($class)){
include $class;
}else{
echo sprintf("%s does not exists", $class);
}
}
}
//__autoload()函数只能存在一次,spl_autoload_register()能注册多个函数
spl_autoload_register("Lib\\AutoLoad::loadClass", true, true);
Lib/Cache/Cache.php
<?php
/*
cache基类
*/
namespace Lib\Cache;
class Cache{
/*
简单工厂调用
*/
public static function Factory($cacheType, $options = []){
try {
if(!$cacheType) throw new \Exception('cacheType can not be empty');
// 获取缓存类名
$class = ucfirst($cacheType);
// if(!in_array($class, ['File'])) throw new \Exception("cache:{$class} is not supported");
$className = __NAMESPACE__ . '\\' . $class;
return new $className($options);
} catch (\Exception $e) {
echo $e->getMessage();
return false;
}
}
}
Lib/Cache/Interfaces/CacheInterface.php
<?php
/*
缓存类接口
虽然会使用不同类型的缓存类,但是通过抽象一个缓存类接口来把所有缓存的设置,更新方法等的方法名和参数约束起来
定义不同类型缓存公用的方法
*/
namespace Lib\Cache\Interfaces;
interface CacheInterface{
/**
* 设置缓存
* @param $key
* @param $value
* @param $ttl
* @return mixed
*/
public function save($key, $value, $ttl);
/**
* 获取缓存
* @param $key
* @return mixed
*/
public function get($key);
/**
* 删除缓存
* @param $key
* @return mixed
*/
public function delete($key);
/**
* 自增操作
* @param $key
* @param $value
* @return mixed
*/
public function increment($key, $value=1);
/**
* 自减操作
* @param $key
* @param $value
* @return mixed
*/
public function decrement($key, $value=1);
/**
* 清空缓存
* @return mixed
*/
public function flush();
}
Lib/Cache/File.php
<?php
namespace Lib\Cache;
use Lib\Cache\Interfaces\CacheInterface;
class File implements CacheInterface{
protected $preFix = 'a.s.d.f'; //key前缀
//protected $cacheDir = ROOT . '/store'; //缓存存放目录(PHP7适用)
protected $fileExt = '.caches';//缓存文件扩展名
public function __construct($options = []){
$this->cacheDir = ROOT . '/store'; //缓存存放目录(PHP5写法)
if(!empty($options['pre_fix'])) $this->preFix = $options['pre_fix'];
if(!empty($options['file_ext'])) $this->fileExt = $options['file_ext'];
}
/**
* 设置缓存
* @param $key
* @param $value
* @param int $ttl 缓存存活秒数
* @return mixed
*/
public function save($key, $value, $ttl = 3600){
if(!$key || !$value) return false;
//获取缓存文件名
$cacheFile = $this->getCacheFile($key);
//创建缓存目录
$cacheDir = dirname($cacheFile);
if(!is_dir($cacheDir)){
if(!mkdir($cacheDir, 0777, true)) return false;
}
//写文件
if(file_put_contents($cacheFile, $value, LOCK_EX) !== false){
@touch($cacheFile, $ttl + time());
return true;
}else{
return false;
}
}
/**
* 获取缓存
* @param $key
* @return mixed
*/
public function get($key){
if(!$key) return false;
$cacheFile = $this->getCacheFile($key);
if(!file_exists($cacheFile)) return false;
//判断缓存存活时间
if(filemtime($cacheFile) > time()){
return file_get_contents($cacheFile);
}else{
@unlink($cacheFile);
}
return false;
}
/**
* 自增操作
* @param $key
* @param $value
* @return mixed
*/
public function increment($key, $value = 1){
if(!$key) return false;
$cacheFile = $this->getCacheFile($key);
if(!file_exists($cacheFile)) return false;
//判断缓存存活时间
if(filemtime($cacheFile) > time()){
$content = file_get_contents($cacheFile);
$content += $value;
if($this->save($key, $content)) return $content;
}
return false;
}
/**
* 自减操作
* @param $key
* @param $value
* @return mixed
*/
public function decrement($key, $value = 1){
return $this->increment($key, -$value);
}
/**
* 删除缓存
* @param $key
* @return mixed
*/
public function delete($key){
if(!$key) return true;
@unlink($this->getCacheFile($key));
return true;
}
/**
* 清空缓存
* @return mixed
*/
public function flush(){
return $this->deleteCacheDir($this->cacheDir);
}
/**
* 获取缓存文件
* @param $key
* @return bool|string
*/
public function getCacheFile($key){
if(!$key) return false;
$key = $this->preFix . $key; //连接前缀
$str = sha1($key); //做一个哈希值,非法的字符串转成正常字符串
return $this->cacheDir . '/' . substr($str, 0, 2) . '/' . substr($str, 2, 2) . '/' . substr($str, 4) . $this->fileExt;
}
/**
* 递归删除缓存目录
* @param $dir
* @return bool
*/
public function deleteCacheDir($dir){
if(($handle = opendir($dir)) !== false){
while(($file = readdir($handle)) !== false){
if($file[0] === '.') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
if(is_file($path)){
@unlink($path);
}else{
$this->deleteCacheDir($path);
}
}
@rmdir($dir);
closedir($handle);
}
return true;
}
}