缓存对静态或低频更新页面最有效,如产品列表页、帮助文档等;若页面含登录态、购物车等动态内容则禁用,否则导致数据错乱。

缓存对静态或低频更新页面最有效
视图缓存只在输出完全由控制器生成、不依赖实时用户状态或动态会话数据时才安全生效。比如产品列表页、帮助文档、博客归档页——这些内容更新频率低(几小时甚至几天一变),且不显示“欢迎,$user->name”这类个性化内容。
如果页面包含登录态判断、购物车数量、未读消息计数,或者使用了 $this->session->userdata()、$_COOKIE、$_GET 参数做逻辑分支,开启 $this->output->cache(60) 后,所有用户看到的都是同一份缓存副本,会直接导致数据错乱。
- 适合场景:CMS 文章页、公司介绍页、API 响应模板(无鉴权)、SEO 友好型落地页
- 不适合场景:后台仪表盘、会员中心、搜索结果页(含分页参数)、带表单 CSRF token 的页面
- 注意:
$this->output->cache()不识别 URI 中的查询字符串,默认把/blog?id=1和/blog?id=2当作同一个缓存键,除非你在 CI4 中显式启用$cacheQueryString = true
文件系统性能决定缓存是否真能提速
CodeIgniter 的视图缓存本质是把 view 渲染后的 HTML 写入 application/cache/ 目录下的文件,下次请求直接读取并输出。这省去了加载模型、执行查询、解析视图模板的全过程。
但前提是磁盘 I/O 快。在共享主机或 NFS 挂载的存储上,频繁读写缓存文件反而比跑一次轻量查询更慢;而在本地 SSD 或 tmpfs(内存文件系统)上,效果立竿见影。
- 检查点:确保
application/cache/目录存在且权限为0755或0777(CI3);CI4 则看WRITEPATH . 'cache/'是否可写 - 警告:某些云环境(如 AWS Lambda、Vercel Edge Functions)根本不允许写文件,
$this->output->cache()会静默失败 - 替代方案:若文件缓存不可靠,CI4 更推荐用
RedisHandler或MemcachedHandler,它们不依赖本地磁盘
缓存时间设太长会导致内容陈旧,设太短等于没开
$this->output->cache(5) 表示缓存 5 分钟,过期后下一次请求才会重新生成。这个值不是越小越好,也不是越大越好——它必须匹配你内容的真实更新节奏。
例如一个新闻首页每 15 分钟由定时任务拉取新标题,缓存设成 10 分钟就合理;但如果设成 1 分钟,大量并发请求会在过期瞬间同时击穿缓存,触发多次重复渲染,反而加重负载。
- 经验法则:缓存时间 ≥ 内容平均更新间隔 × 1.5,且不超过该内容业务容忍的陈旧上限
- CI3 中不能用秒级精度(
1/60是 hack,不稳定);CI4 的$ttl单位是秒,支持30这样的精确值 - 切勿全局设
$this->output->cache(1440)(24 小时)——除非你确认这页一年都不改,否则迟早被投诉“怎么删了文章还显示?”
清除缓存的动作必须主动触发,不能等自动过期
CI 的视图缓存文件不会自我清理,只靠时间戳判断是否过期。这意味着:即使你已删除 $this->output->cache() 调用,旧缓存文件仍躺在磁盘上,直到被新请求覆盖或手动删除。
尤其在内容管理系统中,每次发布新文章、修改分类、删除评论,都必须同步清掉相关缓存目录。否则用户刷新页面,看到的还是上周的旧数据。
- CI3 清除方式:调用
$this->output->delete_cache('/blog')(路径需匹配 URI 段)或直接delete_files(APPPATH . 'cache/', true) - CI4 清除方式:用
cache()->deleteMatching('blog*')或直接删WRITEPATH . 'cache/'下对应子目录 - 最容易被忽略的一点:缓存键基于完整 URI 路径生成,
/blog/latest和/blog/latest/(结尾斜杠差异)是两个不同缓存,必须分别清除











