商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > ThinkPHP查询缓存怎么设_ThinkPHPRedis缓存加速介绍【教程】

ThinkPHP查询缓存怎么设_ThinkPHPRedis缓存加速介绍【教程】

  发布于2026-07-08 阅读(0)

扫一扫,手机访问

在开发中遇到 Cache::get() 返回 null,是件挺让人头疼的事。很多时候,问题根源并不复杂,就是缓存驱动根本没切换成功,你却浑然不知。

一个最直接的排查方法:执行下 php -r "var_dump(cache('test', 'ok', 10)); var_dump(cache('test'));"。如果第二次输出 bool(false),那基本就能断定,缓存链路压根就没通。这时候,你需要逐一确认三处硬性配置:

  • 检查 config/cache.php 文件,确保 default 的值是小写的 'redis',不是 'Redis''REDIS',这些细节是会“静默”失效的。
  • stores.redis 下的配置块必须完整。特别注意 select 参数的值必须是整数,如果写成字符串 "0",一样会失败。另外,即便没有密码,password 也得显式写成空字符串 ''
  • 最关键的一步,确认你的 PHP 环境确实装了 Redis 扩展。在终端跑一下 php -m | grep redis,或者看 phpinfo() 页面里有没有 Redis 模块,这是最直接的证据。

给 Db 查询加缓存,_cache() 参数得是数组

_cache() 这个方法有点特殊。很多人误以为它是 Db 类的一个内置方法,其实不然。它是查询构造器的一个“钩子”,只在 selectfindvalue 这些执行方法前调用才有效。如果你写成 Db::table('user')->where()->_cache()->select(),大概率会直接报“方法未定义”的错误。

正确的姿势应该是这样:

Db::table('user')
    ->where('status', 1)
    ->_cache(['user_active_list', 1800, 'user'])
    ->select();

这里有三个关键点需要留意:

  • 传给 _cache() 的参数必须是数组,且顺序固定为:[缓存键, 过期秒数, 标签]。传个字符串或数字进去是无效的。
  • 缓存键的命名是门学问。建议带上业务标识和查询条件的哈希值,比如 'user_list_' . md5($status . '_' . $type),这样能避免不同参数组合互相干扰。
  • 第三个参数“标签”不是摆着好看的。它决定了你能不能优雅地进行批量清理,比如用 Cache::tag('user')->clear() 一次性清除所有用户相关的缓存。

模型 cache(true) 不区分条件,手动拼 key 才靠谱

很多新手会这么写:UserModel::where('status', $status)->cache(true)->select()。粗看没问题,但实际上生成的缓存键只包含了类名和方法名(像 think:UserModel:select),这意味着所有不同的 $status 值都会共用同一个缓存,最终导致脏数据。

要实现按条件隔离缓存,有两种靠谱的做法:

  • 使用数组方式:cache(['user_list', $status, $type], 300),ThinkPHP 会自动帮你序列化成一个稳定的字符串。
  • 手动拼接字符串:cache('user_list_' . md5($status . '_' . $type), 300),这种方式更可控,排查问题时也更直观。
  • 千万别依赖 with('profile') 这种关联预载入会自动加入缓存键,它不参与键的生成。查询 with('profile')with('posts') 的结果可能会互相污染。

Cache::remember() 缓存失效,闭包里声明变量了吗?

Cache::remember('user_'.$id, 3600, function () use ($id) { return User::find($id); }) 这种写法是安全的。但如果你漏掉了 use ($id),写成 function () { return User::find($id); },问题就来了。ThinkPHP 6 会把整个闭包序列化后作为 key 的一部分,导致每次执行都生成一个不同的 key,结果就是“写进去了,但读不出来”。

还有个更隐蔽的坑是序列化失败。如果闭包里面用到了 $thisRequestQuery 这样的对象,serialize() 会悄悄失败,缓存的值就变成了空。一个通用的解决方案是:写入前先用 json_encode() 处理,读取时再用 json_decode() 还原,这样可以绕过 PHP 序列化的那些限制。

最后,一个最容易被忽略的细节:缓存键里不要包含空格或中文,尤其在 file 驱动下,这会导致文件写入失败且没有任何报错。最稳妥的兜底方案,就是统一用 md5($key) 来处理,或者只保留字母、数字和下划线。

本文转载于:https://www.php.cn/faq/2417488.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注