Laravel使用Cache::remember缓存首页数据报Closure序列化错误如何解决
问题原因
你代码存在两个核心问题,直接触发了Serialization of 'Closure' is not allowed报错:
- 你直接将
view()方法返回的未渲染视图实例作为缓存内容存储,视图实例内部包含大量闭包方法,PHP原生不支持对闭包进行序列化存储,缓存写入时直接触发报错。你需要缓存的是视图渲染后的HTML字符串,或者仅缓存查询得到的数据集,不能直接存储未渲染的视图实例。 - 部分查询构造器没有执行查询触发数据返回:
$breakingNews = BreakingNews::published();末尾没有调用->get()/->first()等执行方法,返回的是查询构造器对象,内部也包含闭包逻辑$quizzes = Quizze::quizOrderBy();同样没有调用执行方法,返回的也是查询构造器对象
- 额外注意:你设置的缓存时长数值不符合需求,你需要6分钟缓存,代码里写的是
600,且Laravel 5.8及以上版本Cache::remember第二个参数单位为秒,更早版本单位为分钟,注意对应调整。
修复后的代码
以下是缓存页面渲染HTML的修复方案:
public function index() { $rememberKey = 'homepage-data'; // 6分钟对应360秒,如果是Laravel 5.8以下版本(单位为分钟)这里填6即可 $ttl = 360; return \Cache::remember($rememberKey, $ttl, function () { // 所有查询都调用执行方法获取数据集,避免返回查询构造器 $breakingNews = BreakingNews::published()->get(); $rightSlider = Article::rightSlider()->take(20)->get(); $leftSlider = Article::leftSlider()->take(9)->get(); $shows = Show::publishedOrderShows()->take(10)->get(); $blogs = Article::allBlogs()->take(12)->get(); $latestNews = Article::latestNews()->whereNotIn('id', $rightSlider->pluck('id')->merge($leftSlider->pluck('id')))->take(5)->get(); $otherNews = Article::otherNews()->whereNotIn('id', $rightSlider->pluck('id')->merge($leftSlider->pluck('id')))->take(2)->get(); $otherNewsDown = Article::otherNews()->whereNotIn('id', $rightSlider->pluck('id')->merge($leftSlider->pluck('id'))->merge($otherNews->pluck('id')))->take(8)->get(); $analyticNews = Article::allAnalytics()->take(4)->get(); $populars = Article::popular()->take(10)->get(); $quizzes = Quizze::quizOrderBy()->get(); // 调用render()方法获取渲染后的HTML字符串,支持正常序列化缓存 return view('pages/home-page')->with([ 'breakingNews' => $breakingNews, 'rightSlider' => $rightSlider, 'leftSlider' => $leftSlider, 'shows' => $shows, 'blogs' => $blogs, 'latestNews' => $latestNews, 'otherNews' => $otherNews, 'otherNewsDown' => $otherNewsDown, 'analyticNews' => $analyticNews, 'populars' => $populars, 'quizzes' => $quizzes ])->render(); }); }
补充说明
如果你后续需要对查询数据做其他处理,也可以选择仅缓存所有查询到的数据集,在缓存命中后再传入视图渲染,灵活度更高。
内容的提问来源于stack exchange,提问作者Irakli
相关产品推荐
相关产品推荐

