缓存(Cache)
Mtphp\Cache\FileCache —— 极简文件缓存,零配置即可用(无需 Redis 等额外服务)。框架同时内置 RedisStore(纯 PHP RESP 实现,同样零依赖,详见 12.1),经 CacheManager 按 config('cache.driver') 透明切换,调用方式完全一致。
// 方式一:全局助手 cache()(推荐,自动按配置选择驱动)
cache()->set('name', '张三', 600); // 存 10 分钟
$v = cache()->get('name', '默认值'); // 取;过期或缺失都返回默认值
$list = cache()->remember('hot', 60, fn () => 查库得到热门列表()); // 未命中才执行回调并写入
// 方式二:直接 new(文件驱动)
$c = new \Mtphp\Cache\FileCache('runtime/cache', 3600); // 目录、默认过期秒数(0=永不过期)
$c->has('name'); // 是否存在且未过期
$c->delete('name'); // 删除单个键
$c->clear(); // 清空整个缓存目录
要点:
- 写入时记录过期时间,读取时自动判断是否过期(过期即删除并返回默认值)。
remember()是日常最常用的方法:把“算起来贵”的结果(如聚合查询)缓存起来。- 缓存文件带
<?php安全头,即便误放到 Web 目录也无法被直接执行。 - 可选配置
config/cache.php:path(缓存目录)、ttl(默认过期秒数)、driver(缓存驱动)。不配置则用框架默认值(文件驱动)。
12.1 Redis 驱动(零依赖,纯 PHP RESP 实现)
默认文件缓存适合单服务器;多服务器 / 分布式共享缓存可改用 Redis,且无需安装 ext-redis 扩展或 predis 依赖——框架用 stream_socket 手写 RESP 协议(Mtphp\Cache\RedisConnector / Mtphp\Cache\Resp),守住“零依赖”红线(与 HTTP 客户端用 curl 而非 Guzzle 的取舍一致)。
// config/cache.php
return [
'driver' => 'redis', // file(默认)| redis
'host' => '127.0.0.1',
'port' => 6379,
'db' => 0,
'password'=> null,
'timeout' => 2.0,
'prefix' => '',
];
// 业务代码:与文件驱动完全一致,无需改调用
cache()->set('k', $v, 600); // 底层走 Redis SET ... EX(原生过期,不依赖本进程时钟)
cache()->remember('hot', 60, fn () => 查库());
要点:
- 文件驱动(
FileCache)与 Redis 驱动(RedisStore)都实现Mtphp\Cache\CacheInterface,经CacheManager::resolve()(即cache()助手)透明切换;新增驱动只需实现该接口并扩展CacheManager。 - Redis 值以
serialize(['_v' => $value])包裹写入,可正确区分“未命中”与“存了false/null”;过期交给 Redis 原生EXPIRE,clear()对应FLUSHDB。 - 连接懒建立:仅在首次发命令时建连;未配置 Redis 却切到
redis驱动时,首个缓存操作会抛异常,便于尽早暴露配置问题。
线上演示:访问
/demo/cache多次,可见visits计数自增(缓存跨请求持久)、hot_list命中缓存。