ci4 已移除 $this->output->cache(),需改用 cache() 辅助函数或 cacheinterface;redis 缓存失效常因 cache_handler 配置错误或扩展未启用;数据库缓存须用 withcaching();内存暴涨多因重复实例化,应使用 service() 共享实例。

为什么 $this->output->cache(30) 在 CI4 里完全没反应
因为 CodeIgniter 4 已彻底移除 $this->output->cache() 这个方法——它只存在于 CI3。你在 CI4 控制器里写这行代码,框架会直接忽略,不报错也不生效。
CI4 的缓存必须走统一的 cache() 辅助函数或 CacheInterface 实例,且仅对响应内容(如 view 渲染结果)有效,不是“页面级缓存开关”。
- 正确写法是:在控制器方法末尾用
return cache('home_page', function() { return view('home'); }, 30); - 或者先生成内容再显式保存:
cache()->save('key', $html, 30); - 注意:
cache()不会自动包装整个请求流程,它只缓存你传进去的 callable 返回值 - 若你仍想实现类似 CI3 的“整页缓存”,得自己在中间件或 BaseController 的
after()钩子中拦截响应体并存取
Redis 缓存配好了却总 fallback 到 file 驱动
最常见原因是 CACHE_HANDLER 环境变量没被正确读取,或 Redis 连接失败后框架静默降级——它不会抛异常,只会默默切到 file。
验证步骤:var_dump(cache()->getHandlerName()); 必须返回 'redis',否则配置未生效。
- 检查
.env文件:确保CACHE_HANDLER=redis未被注释,且没有空格或 UTF-8 BOM - 确认 PHP 已加载 redis 扩展:
php -m | grep redis,无输出就需安装php-redis - 检查
app/Config/Cache.php中$redis配置块的host、port是否可连(用redis-cli -h xxx -p xxx ping测试) - 若使用密码,
password字段不能为null,要写成空字符串''或实际密码
数据库查询变慢,但 $this->db->cache_on() 报错
CI4 废弃了 cache_on()/cache_off() 这套 API。现在数据库查询缓存必须通过查询构造器的 withCaching() 方法启用,且仅对 get()、getWhere() 等读操作有效。
错误写法:$this->db->cache_on()->get('users'); → 报 Call to undefined method
正确写法:$this->db->table('users')->withCaching()->get();
-
withCaching()默认使用全局缓存配置,也可传 TTL:withCaching(60) - 缓存键基于完整 SQL + 绑定参数生成,
where('status', 1)和where('status', 2)是两个独立缓存项 - 注意:JOIN 查询、子查询、
SELECT *会显著增大缓存体积,建议明确字段列表 - 如果模型里用了
protected $useSoftDeletes = true,软删除字段过滤逻辑会参与缓存键计算,务必留意
上线后内存暴涨,memory_limit 调高只是掩耳盗铃
真正的问题往往出在服务实例重复构造和 autoload 泛滥上——每个请求都 new 一遍 Email、Session、Validation,内存自然叠加上去。
CI4 的 Services 类就是为此设计的:它默认返回共享实例,避免重复初始化。
- 别再手动
new \CodeIgniter\Email\Email(),改用service('email') - 检查
app/Config/Autoload.php:把$libraries和$helpers清空,只在真正需要的地方按需加载 - 高频工具类(如 JWT、HTTP 客户端)务必注册进
app/Config/Services.php,并设$getShared = true - 部署时执行
composer dump-autoload --optimize,能减少自动加载搜索路径,降低启动内存
缓存驱动没切 Redis、日志还开着 debug 级别、环境变量仍是 development——这三个点只要漏一个,其他所有优化都白搭。










