ShopXO 缓存速查手册
核心结论
| 命题 |
结论 |
| 数据库查询自动缓存? |
❌ 否,必须手动显式包裹 |
| 哪些查询被缓存? |
仅代码中用 MyCache() / cache() 包装的 |
Db::name('x')->find() 自动走 Redis? |
❌ 直击 DB,无中间层 |
| 缓存驱动切换 |
由后台 common_data_is_use_redis_cache 控制(0=file, 1=redis) |
| Redis 参数来源 |
从数据库配置表读取(host/port/password) |
缓存调用方式
ShopXO 自有的 MyCache()
// 读取(为空触发重新查询)
$data = MyCache($key);
// 写入(第三参数 = 秒数 expire)
MyCache($key, $data, 3600);
// 删除
MyCache($key, null);
ThinkPHP 原生 cache()
cache($key, $value, $expire_seconds);
cache($key, null); // 删除
vr_ticket 插件缓存策略
缓存场景
| 数据 |
缓存时间 |
原因 |
| 座位模板(vr_seat_templates) |
86400s(1天) |
静态数据,变更少 |
| 商品座位图渲染数据 |
3600s(1小时) |
商品信息不频繁改 |
| 核销记录列表 |
300s(5分钟) |
需要一定实时性 |
| 观演人信息 |
❌ 不缓存 |
隐私数据 |
| 座位实时余量 |
❌ 不缓存 |
强一致性要求,走 DB |
缓存 Key 规范
vrticket:seat_template_{id} # 单个模板
vrticket:seat_templates_list # 模板列表
vrticket:goods_seat_map_{goods_id} # 商品座位图
vrticket:verifications_list # 核销记录列表
数据变更时主动失效
// 模板更新后
cache('vrticket:seat_template_' . $id, null);
cache('vrticket:seat_templates_list', null);
// 核销记录新增后
cache('vrticket:verifications_list', null);
配置说明(config/cache.php)
'default' => (MyFileConfig('common_data_is_use_redis_cache','',0,true) == 1) ? 'redis' : 'file',
'stores' => [
'redis' => [
'host' => MyFileConfig('common_cache_data_redis_host','','127.0.0.1',true),
'port' => MyFileConfig('common_cache_data_redis_port','',6379,true),
'password' => MyFileConfig('common_cache_data_redis_password','','',true),
'expire' => intval(MyFileConfig('common_cache_data_redis_expire','',0,true)),
'prefix' => MyFileConfig('common_cache_data_redis_prefix','','redis_shopxo',true),
],
]
- 全局
expire = 0 表示永久(受实际 per-key expire 覆盖)
- ShopXO 后台可配置
common_data_is_use_cache 全局开关(debug 模式下自动 bypass)
防坑提示
- Debug 模式绕过缓存:
MyEnv('app_debug') 为 true 时所有 MyCache() 直接 miss
- 全局开关:
MyC('common_data_is_use_cache') != 1 时全部走 DB
- 超卖风险:座位状态查询禁止缓存,必须实时查 DB +
FOR UPDATE SKIP LOCKED
- MyCache 静态复用:同一请求内同一 key 只调一次底层
cache()(in-request 内存缓存)
快速上手模板
// 读缓存
$key = 'vrticket:seat_template_' . $templateId;
$data = MyCache($key);
if ($data === null) {
$data = Db::name('SeatTemplate')->where(['id'=>$templateId])->find();
MyCache($key, $data, 86400);
}
// 写操作后清缓存
cache('vrticket:seat_template_' . $templateId, null);