memcached在laravel中需同时满足php扩展启用、config/cache.php正确配置、.env中cache_driver=memcached三者,缺一不可;常见错误包括扩展名误为memcache、port未设0(unix socket时)、服务地址协议不匹配或配置缓存未清除。

Memcached 在 Laravel 中不是“装了扩展就能直接用”,必须同时满足驱动配置、服务可达、客户端兼容三个条件,缺一不可。很多报 Class 'Memcached' not found 或缓存不生效的问题,根源都在这三者之一没对齐。
确认 PHP 环境已启用 Memcached 扩展
这是最常被跳过的前置步骤。Laravel 的 memcached 驱动依赖 PHP 的 Memcached 类(注意大小写),不是 memcache(旧版)扩展。
- 运行
php -m | grep memcached,必须看到memcached(非memcache) - 如果没输出,需安装:Ubuntu/Debian 用
sudo apt install php-memcached,CentOS/RHEL 用sudo yum install php-pecl-memcached - 重启 Web 服务或 PHP-FPM:
sudo systemctl restart php-fpm或sudo systemctl restart apache2 - 在控制器里临时加一行
dd(class_exists('Memcached'));,返回true才算通过
配置 config/cache.php 的 memcached 连接参数
Laravel 不读 /etc/memcached.conf,它只认 config/cache.php 里 'memcached' 键下的数组。UNIX socket 和 TCP 是两种互斥写法,混用会静默失败。
- TCP 方式(默认):
'memcached' => [ [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 ] ] - UNIX socket 方式(性能略优,需确保权限):
'memcached' => [ [ 'host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100 ] ]注意port必须为0,否则 Laravel 仍尝试走 TCP - 多个服务器?别手写数组,用
env()拆分,例如:'host' => env('MEMCACHED_HOST', '127.0.0.1'),避免部署时硬编码
切换 CACHE_DRIVER 并验证是否生效
仅改配置文件不生效,.env 中的 CACHE_DRIVER 必须显式设为 memcached,且不能残留空格或中文引号。
- 检查
.env:CACHE_DRIVER=memcached(无空格、无引号、全小写) - 清除配置缓存:
php artisan config:clear;若之前跑过config:cache,新配置不会热加载 - 写个测试路由验证:
Route::get('/cache-test', function () { Cache::put('test_key', 'test_value', 60); return Cache::get('test_key') === 'test_value' ? 'OK' : 'FAIL'; }); - 如果返回
FAIL,用php artisan tinker手动连:(new Memcached)->addServer('127.0.0.1', 11211)->set('x', 'y'),看是否抛异常
Cache::forever() 存的数据为什么查不到?
Cache::forever() 底层调的是 Memcached::set() 并传 0 作为过期时间,但某些 Memcached 服务版本(如 1.6+)对 0 的解释是“禁用 TTL”,而另一些则视为“立即过期”。这不是 Laravel Bug,而是协议实现差异。
- 生产环境慎用
forever(),改用超长 TTL,比如Cache::put('key', $val, 365 * 24 * 60) - 必须用永久缓存?先确认 Memcached 服务端版本:
echo "version" | nc 127.0.0.1 11211,再查对应版本文档中expire参数行为 - 调试时别只信
Cache::get(),用命令行直连验证:echo "get test_key" | nc 127.0.0.1 11211,排除 Laravel 层干扰
真正卡住人的地方往往不在代码怎么写,而在 PHP 扩展名拼错、.env 缓存没清、或者 Memcached 服务监听在 IPv6 地址却用 IPv4 去连——这些细节不打日志、不看网络层,光盯 Laravel 代码永远找不到根因。











