如何利用ThinkPHP模型字段只读虚拟字段实现缓存与多源合成字段持久化?
- 内容介绍
- 文章标签
- 相关推荐
本文共计963个文字,预计阅读时间需要4分钟。
伪原创改写如下:
getXXXAttr 计算字段不会进模型缓存
getXXXAttr 方法在 toArray()、toJson() 或模板渲染时才执行,属于运行时动态计算,不落库也不进模型查询缓存。即使你对主模型调用了 cache(true),比如 User::cache(true)->find(1),缓存里存的仍是原始数据库字段,full_name 这类虚拟字段每次都会重新计算。
- 缓存命中后返回的是原始
$data数组,getXXXAttr不会自动触发 - 想让虚拟字段“看起来被缓存”,得手动把计算结果塞进缓存值里,比如用
Cache::set('user_1_full', $user->full_name, 3600) - 别依赖
$model->getData()——它跳过所有getXXXAttr,只返回原始数据
组合缓存必须显式拼 key,不能靠 with() + cache(true)
with('profile') 预加载后调 cache(true),缓存键是 think_model_User_find_1,跟是否加载 profile、是否用了 getTotalPriceAttr 完全无关。你要缓存“用户+资料+计算总价”这个组合结果,就得自己构造唯一 key。
本文共计963个文字,预计阅读时间需要4分钟。
伪原创改写如下:
getXXXAttr 计算字段不会进模型缓存
getXXXAttr 方法在 toArray()、toJson() 或模板渲染时才执行,属于运行时动态计算,不落库也不进模型查询缓存。即使你对主模型调用了 cache(true),比如 User::cache(true)->find(1),缓存里存的仍是原始数据库字段,full_name 这类虚拟字段每次都会重新计算。
- 缓存命中后返回的是原始
$data数组,getXXXAttr不会自动触发 - 想让虚拟字段“看起来被缓存”,得手动把计算结果塞进缓存值里,比如用
Cache::set('user_1_full', $user->full_name, 3600) - 别依赖
$model->getData()——它跳过所有getXXXAttr,只返回原始数据
组合缓存必须显式拼 key,不能靠 with() + cache(true)
with('profile') 预加载后调 cache(true),缓存键是 think_model_User_find_1,跟是否加载 profile、是否用了 getTotalPriceAttr 完全无关。你要缓存“用户+资料+计算总价”这个组合结果,就得自己构造唯一 key。

