PHP 8.5 使用 Memcached 需确保服务运行、加载 memcached 扩展(非 memcache)、扩展兼容 PHP 8.5;连接后应禁用自动序列化、校验 getResultCode、注意 key 前缀、多节点启用一致性哈希,并推荐批量操作与原子计数。

PHP 8(包括 8.5)使用 Memcached 缓存数据,核心是装对扩展、连对服务、写对代码。最关键的不是“能不能用”,而是“用的是不是 memcached 扩展”——它和早已停滞的 memcache 扩展完全不兼容,函数名、常量、行为都不同。
确认环境已就绪
别急着写代码,先确保三件事都成立:
- Memcached 服务端在运行:
systemctl status memcached或telnet 127.0.0.1 11211能通,stats有响应 - PHP 加载的是 memcached 扩展(不是 memcache):
php -m | grep memcached输出memcached;php -r "var_dump(class_exists('Memcached'));"返回bool(true) - PHP 8.5 兼容性已验证:PECL 上当前发布的
memcached版本必须明确支持 PHP 8.5,不能直接复用 8.2 的 .so 文件
基础连接与读写操作
以下是最小可用示例,注意关键配置点:
$mc = new Memcached();
$mc->addServer('127.0.0.1', 11211);
// 推荐显式关闭自动序列化,避免隐式转换陷阱
$mc->setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_NONE);
// 存字符串或数字(SERIALIZER_NONE 下不支持数组/对象)
$mc->set('user:1001', '{"name":"Leo","role":"dev"}', 300); // 5分钟过期
// 取值后务必检查结果码,不能只判 false
$value = $mc->get('user:1001');
if ($mc->getResultCode() === Memcached::RES_SUCCESS) {
echo $value;
} elseif ($mc->getResultCode() === Memcached::RES_NOTFOUND) {
echo "缓存未命中,需回源加载";
}
避开高频坑点
很多“写进去读不到”问题其实和逻辑无关,而是配置或认知偏差:
立即学习“PHP免费学习笔记(深入)”;
-
Key 被前缀污染:默认开启
Memcached::OPT_PREFIX_KEY,你设user:1,实际存的是myapp_user:1。如不需要,加一行:$mc->setOption(Memcached::OPT_PREFIX_KEY, ''); -
set() 返回 true 不代表成功写入:它可能只是“跳过更新”(比如 key 已存在且未强制覆盖)。始终用
getResultCode()判断 -
连接多个节点时没启用一致性哈希:若要做分布式分片,需开启:
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); - PHP-FPM 进程间不共享 Memcached 实例:每次 new 都是新连接,不要在 long-running 进程外反复 new,可考虑封装为单例或依赖注入
实用增强技巧
让缓存真正落地、可控、易维护:
- 批量操作提效:
$mc->getMulti(['user:1', 'user:2', 'config:site'])比循环 get 快得多 - 数值型原子操作:
$mc->increment('counter:login', 1)或$mc->decrement('rate_limit:ip_192.168.1.100', 1) - 会话直连:
session.save_handler = memcached+session.save_path = "127.0.0.1:11211",无需改业务代码 - 简单监控:
print_r($mc->getStats());查看命中率、内存使用、连接数等



















