CI数据库查询缓存仅对SELECT生效且不自动过期,需手动清除;缓存目录需可写,清除时须严格按控制器类名(小写、无Controller后缀)和方法名(小写)调用cache_delete()。

CI 的数据库查询缓存只对 SELECT 生效,且不自动过期
你改了 SQL 或数据库里加了新数据,页面却还显示旧结果——这不是代码没跑,而是 $this->db->cache_on() 生成的缓存文件一直躺在 application/cache/db/ 下,没人动它。CI 的 DB 缓存机制很“老实”:只要没调清除指令,哪怕过了一年,它也照用不误。
- 只有
SELECT查询会被缓存;INSERT/UPDATE/DELETE不进缓存,也不触发自动清理 - 缓存目录必须可写(如
755或777),否则根本不会生成文件,你以为开了缓存,其实压根没生效 - 缓存按控制器类名 + 方法名建子目录(如
blog/index),大小写敏感,拼错一个字母就清不掉
清除指定页面的 DB 缓存必须传对两个参数
$this->db->cache_delete('blog', 'index') 看着简单,但实际踩坑最多:第一个参数是控制器类名(不含 Controller 后缀,且首字母小写),第二个是方法名(小写)。比如类 BlogController 里的 public function ListAll(),正确写法是 $this->db->cache_delete('blog', 'listall')。
- CI3 和 CI4 都遵循这个命名规则,不是 URI 路径,也不是路由别名
- 如果用了 HMVC 模块结构,类名前缀(如
admin_blog)也要完整带上 - 不确定类名怎么写?在控制器里临时加一行
log_message('error', 'class: '.get_class($this).', method: '.__METHOD__);,看日志输出再抄
批量清除或开发阶段快速重置的实操方式
上线后不敢乱清全库,但开发时频繁改数据,手动一个个删太慢。这时候要分场景选方法:
- 清当前控制器所有缓存:
$this->db->cache_delete_all()—— 它会删掉整个application/cache/db/下该控制器对应的所有子目录 - 清全部 DB 缓存(慎用):
$this->db->cache_delete_all()不带参数,直接扫光db/目录下所有内容 - 命令行清空(CI4 推荐):在项目根目录运行
php spark cache:clear,它会连带清掉路由、配置等其他缓存,避免漏项 - 最暴力但最可靠(开发机):直接
rm -f application/cache/db/*,注意别误删目录本身
缓存失效却“看起来没清”,大概率是浏览器或 CDN 拦住了
你确认 $this->db->cache_delete('user', 'profile') 执行成功,application/cache/db/user/profile/ 里文件也没了,但刷新页面还是旧数据——这时候问题不在 CI,而在 HTTP 层。
- 浏览器可能强缓存了 HTML 响应,按
Ctrl+F5或Cmd+Shift+R硬刷新 - 如果用了 Nginx 或 Cloudflare,它们默认缓存
200响应,需在响应头加Cache-Control: no-cache或手动 purge CDN 缓存 - CI4 的 PageCache 过滤器(若启用)会把整页写到
writable/cache/,和 DB 缓存无关,得单独清那里
缓存键是静态绑定的,一旦生成就和代码逻辑脱钩;你删了缓存文件,但忘了在业务关键点(比如保存成功后)补上 cache_delete() 调用,下次用户访问照样走旧数据。











