Files
freeshop/includes/Cache.php
T
2026-08-14 10:55:06 +08:00

156 lines
4.1 KiB
PHP

<?php
/**
* 文件缓存系统
*
* 将数据序列化后写入 storage/cache/ 目录。
* 支持设置 TTL(过期时间)、标签清除、全局清除。
*
* 用法:
* Cache::put('user_123', $data, 3600); // 缓存 1 小时
* $data = Cache::get('user_123'); // 读取(过期返回 null)
* Cache::forget('user_123'); // 删除单个
* Cache::clear(); // 清除全部
*/
if (!defined('IN_APP')) exit('Forbidden');
class Cache
{
/** @var string 缓存目录 */
private static $dir;
/** @var bool 是否启用 */
private static $enabled = true;
/** @var string 缓存文件扩展名 */
const EXT = '.cache';
/**
* 初始化缓存系统。
* @param string $dir 缓存目录路径
* @param bool $enabled 是否启用
*/
public static function init($dir, $enabled = true)
{
self::$dir = rtrim($dir, '/\\');
self::$enabled = $enabled;
if (!is_dir(self::$dir)) {
@mkdir(self::$dir, 0755, true);
}
}
/**
* 写入缓存。
* @param string $key 缓存键
* @param mixed $value 值(任意可序列化类型)
* @param int $ttl 有效期(秒),0=永不过期
* @return bool
*/
public static function put($key, $value, $ttl = 3600)
{
if (!self::$enabled) return false;
$file = self::fileName($key);
$data = [
'expires' => $ttl > 0 ? time() + $ttl : 0,
'created' => time(),
'value' => $value,
];
$content = serialize($data);
return (bool)@file_put_contents($file, $content, LOCK_EX);
}
/**
* 读取缓存。过期或不存在返回默认值。
* @param string $key
* @param mixed $default 不存在时的默认值
* @return mixed
*/
public static function get($key, $default = null)
{
if (!self::$enabled) return $default;
$file = self::fileName($key);
if (!file_exists($file)) return $default;
$content = @file_get_contents($file);
if ($content === false) return $default;
$data = @unserialize($content);
if (!is_array($data)) {
@unlink($file);
return $default;
}
// 检查过期
if ($data['expires'] > 0 && time() > $data['expires']) {
@unlink($file);
return $default;
}
return $data['value'];
}
/**
* 检查缓存是否存在且未过期。
*/
public static function has($key)
{
return self::get($key, '__NOT_FOUND__') !== '__NOT_FOUND__';
}
/**
* 删除单个缓存。
*/
public static function forget($key)
{
$file = self::fileName($key);
if (file_exists($file)) {
return @unlink($file);
}
return true;
}
/**
* 清除所有缓存。
*/
public static function clear()
{
if (!is_dir(self::$dir)) return;
$files = glob(self::$dir . DIRECTORY_SEPARATOR . '*' . self::EXT);
foreach ($files as $f) {
@unlink($f);
}
}
/**
* 带回掉的缓存读取(缓存命中直接返回,未命中执行回调并缓存)。
* @param string $key
* @param int $ttl
* @param callable $callback 无参回调,返回要缓存的值
* @return mixed
*/
public static function remember($key, $ttl, callable $callback)
{
$value = self::get($key, null);
if ($value !== null) return $value;
$value = $callback();
self::put($key, $value, $ttl);
return $value;
}
/**
* 获取或设置(简化版 remember)。
*/
public static function getOrSet($key, $ttl, callable $callback)
{
return self::remember($key, $ttl, $callback);
}
// ─── 内部 ───
private static function fileName($key)
{
// 用 md5 确保文件名安全
return self::$dir . DIRECTORY_SEPARATOR . md5($key) . self::EXT;
}
}