codeigniter中memcached需手动配置且ci3与ci4实现不同:ci3须显式加载driver并设backup降级,ci4则通过.env和cache.php配置handler,不支持自动fallback;连接失败常静默失效,须用telnet和is_supported()等验证。

Memcached 在 CodeIgniter 中不是开箱即用的,必须手动加载驱动、配置连接、处理降级逻辑——尤其是 CI3 和 CI4 的实现方式完全不同,混用会导致 cache()->get() 返回 NULL 或静默失败。
CI3 中加载 Memcached 驱动需显式指定 adapter 和 backup
CI3 默认不启用 Memcached,$this->load->driver('cache') 不会自动识别系统是否装了 memcached 扩展。必须显式传参,并预留降级路径:
- 确保 PHP 已启用
memcached扩展(不是memcache),运行php -m | grep memcached验证 - 在控制器中调用:
$this->load->driver('cache', ['adapter' => 'memcached', 'backup' => 'file']) - 若服务器没装扩展,
backup => 'file'会让缓存退化到application/cache/目录,但要注意该目录必须可写 -
key_prefix强烈建议设置,比如'key_prefix' => 'ci3_prod_',避免多项目共用同一 Memcached 实例时 key 冲突
CI4 中 Memcached 是独立缓存 handler,不是 driver
CI4 彻底重构了缓存系统,cache() 是服务容器注入的单例,不再通过 load->driver 加载。启用 Memcached 必须走配置驱动:
- 修改
.env:设cache.handler = memcached(不能写成memcache) - 确认
app/Config/Cache.php中memcached配置块已启用,且host、port正确(默认是'127.0.0.1'和11211) - 如果用密码认证(如 SASL),需在配置中显式设置
'username'和'password',否则连接直接被拒绝 - CI4 不支持自动 fallback 到 file 缓存,
cache.handler = memcached但服务不可达时,cache()->save()会抛出RuntimeException,必须自己 try/catch
Memcached 连接失败时的典型错误和定位方法
常见现象不是报错,而是缓存读写全部静默失效——cache('key') 始终返回 null,cache()->save() 看似成功但实际没存进去。排查优先级如下:
- 执行
telnet 127.0.0.1 11211,看是否能连上;连不上说明 Memcached 服务没启动或端口被防火墙拦截 - 检查 PHP 错误日志,搜索
Failed to connect to server或Connection refused,CI4 的异常堆栈里会明确指出是MemcachedHandler初始化失败 - CI3 下用
$this->cache->memcached->is_supported()主动检测,返回false就说明扩展未加载或配置无效 - CI4 下可在控制器里临时加一行:
var_dump(cache()->getHandler() instanceof \CodeIgniter\Cache\Handlers\MemcachedHandler);,输出false即代表没走对 handler
缓存键名设计不当导致命中率低
很多人直接用 'user_'.$id 当 key,看似合理,但在高并发下容易因大小写、空格、URL 编码差异造成重复存储。真实项目中应统一标准化:
- 所有 key 必须小写 + 下划线,例如
'user_profile_12345',避免'User_Profile_12345'或'user-profile-12345' - 含参数的 key 要按固定顺序拼接并做
md5(),比如查询条件数组['status' => 'active', 'limit' => 10],应先ksort()再json_encode()再md5() - CI4 的
cache()->save()第三个参数$ttl单位是秒,别误用分钟;设为0表示永不过期,但 Memcached 内存满时仍会被 LRU 清掉 - 不要缓存资源句柄(如 PDO 对象、Resource)、闭包或未序列化的对象——Memcached 只存字符串,PHP 会静默转成空字符串
真正麻烦的从来不是“怎么连上 Memcached”,而是“为什么连上了却没生效”。多数问题出在环境一致性(本地开着服务,测试服没装扩展)、key 命名冲突、或 CI 版本误判 handler 类型。上线前务必在目标环境跑一次 cache()->save('test_key', 'ok', 5) + cache('test_key') 的最小闭环验证。











