php 8.0 必须使用 memcached(带d)扩展和 session.save_handler = memcached,save_path 格式为 host:port(不加 tcp://),否则静默退回到 files 存储。

PHP 8.0 默认不支持 memcache handler,必须用 memcached 扩展 + memcached handler 才能正常工作;直接沿用 PHP 7.x 的 session.save_handler = memcache 会静默失败,$_SESSION 写入无效。
确认已安装并启用 memcached 扩展
PHP 8.0 废弃了旧的 memcache(无 d)扩展,只保留 memcached(带 d)扩展。两者协议兼容但 API 和 session handler 名称不同:
- 运行
php -m | grep memcached,必须看到memcached(不是memcache) - 若未安装:
sudo apt-get install php-memcached(Debian/Ubuntu)或sudo yum install php-pecl-memcached(RHEL/CentOS) - 检查
php.ini中有且仅有一行启用:extension=memcached.so - 重启 PHP-FPM 或 Apache:
sudo systemctl restart php8.0-fpm或sudo systemctl restart apache2
session.save_handler 必须设为 memcached(不是 memcache)
这是最常踩的坑:PHP 8.0 的 session handler 名称和扩展名严格对应,写错就退回到默认 files 存储,毫无报错提示。
- 在
php.ini中设置:session.save_handler = memcached session.save_path = "127.0.0.1:11211"
-
session.save_path格式是host:port,**不加tcp://前缀**(加了会被当作非法 host,连接失败) - 支持多服务器:
session.save_path = "192.168.1.10:11211,192.168.1.11:11211"(逗号分隔,无空格) - 验证是否生效:调用
phpinfo(),搜索Session,确认Registered save handlers包含memcached,且session.save_handler显示为memcached
注意 memcached 的超时机制与 gc_maxlifetime 冲突
Memcached 自带 key 过期能力,而 PHP 的 session GC(垃圾回收)机制对 memcached handler **完全无效**——它只清理 files 类型的过期文件。
-
session.gc_maxlifetime可以仍设为例如1440(24 分钟),但它只影响session_set_cookie_params()生成的 Cookie 过期时间,不影响 Memcached 内部存储的 TTL - 真正控制 session 数据存活时间的是
memcached的写入行为:session_start()本身不会设置 TTL;TTL 由memcached扩展根据session.cookie_lifetime和session.gc_maxlifetime中**较小值**自动应用(PHP 8.0 行为) - 更可靠的做法:显式设置 TTL,在
session_start()前调用:ini_set('session.cookie_lifetime', 1800); ini_set('session.gc_maxlifetime', 1800);,确保两端一致 - 若需自定义 TTL(比如登录态 7 天,临时态 5 分钟),就不能依赖原生 session 机制,得改用
Memcached::set()手动存取
调试 session 是否真进了 Memcached
不要只信 phpinfo(),要验证数据实际落库:
- 写一个测试脚本:
<?php session_name('test'); ini_set('session.save_handler', 'memcached'); ini_set('session.save_path', '127.0.0.1:11211'); session_start(); $_SESSION['debug'] = ['ts' => time()]; echo "Session ID: " . session_id() . "\n"; ?> - 用 telnet 或
memcached-tool检查:echo "get sess_"$(php -r "echo session_id();") | nc 127.0.0.1 11211
如果返回序列化数据(如debug|a:1:{s:2:"ts";i:1726585020;}),说明成功;返回END则没写进去 - 常见失败原因:Memcached 服务未运行、防火墙拦截端口、
save_path地址写错、扩展未加载、PHP 进程用户无权访问 socket(若用 Unix socket)
最关键的细节:PHP 8.0 的 session + Memcached 是「开箱即用但名字敏感」的组合——handler 名、扩展名、save_path 格式三者必须严丝合缝,错一个就回退到文件存储,且不报错。上线前务必用 nc 直连验证键是否存在。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











