如何在AppServiceProvider中统一缓存视图共享数据?
优化视图数据缓存,避免重复代码
首先得帮你理清为什么第一种写法行不通:Cache::remember的核心是缓存闭包返回的数据,但你之前把View::composer的注册逻辑放在了缓存闭包里——这个注册操作本身不返回任何有价值的可缓存内容,而且还会导致视图 composer 只在第一次缓存生效时注册一次,后续缓存有效期内不会重新绑定逻辑,反而会引发问题,所以这种写法从逻辑上就不对。
针对你现在遇到的重复代码问题,我们可以把需要缓存的数据统一整理成配置数组,通过循环来批量处理,不管是3个还是30个查询,都能保持代码简洁:
方案一:统一配置数组(支持自定义缓存时长)
public function boot() { View::composer('*', function ($view) { // 定义所有需要缓存的视图数据,键是视图变量名,值包含缓存时长和查询闭包 $cachedViewData = [ 'home_references' => [ 'ttl' => 60, 'query' => fn() => Reference::where('position', 'home')->orderBy('order', 'asc')->get(), ], 'informations' => [ 'ttl' => 60, 'query' => fn() => ContactInformation::first(), ], 'header_posts' => [ 'ttl' => 60, 'query' => fn() => Post::latest()->limit(4)->get(), ], // 后续新增数据直接在这里加条目即可 ]; // 循环批量绑定缓存后的数据到视图 foreach ($cachedViewData as $variableName => $config) { $view->with( $variableName, Cache::remember($variableName, $config['ttl'], $config['query']) ); } }); }
方案二:默认缓存时长,简化配置
如果大部分数据的缓存时长都相同,我们可以进一步简化,只在需要特殊时长的条目里单独声明:
public function boot() { View::composer('*', function ($view) { $defaultCacheTtl = 60; // 默认缓存60分钟 // 配置数组:键是视图变量名,值默认是查询闭包,特殊情况用数组声明自定义时长 $cachedViewData = [ 'home_references' => fn() => Reference::where('position', 'home')->orderBy('order', 'asc')->get(), 'informations' => ['ttl' => 120, 'query' => fn() => ContactInformation::first()], // 缓存2小时 'header_posts' => fn() => Post::latest()->limit(4)->get(), ]; foreach ($cachedViewData as $variableName => $item) { // 处理缓存时长和查询闭包 $ttl = is_array($item) ? $item['ttl'] : $defaultCacheTtl; $query = is_array($item) ? $item['query'] : $item; $view->with($variableName, Cache::remember($variableName, $ttl, $query)); } }); }
这样一来,不管后续新增多少个需要缓存的视图数据,只需要在数组里添加对应条目,完全避免了重复写Cache::remember的冗余代码,维护起来也更方便。
内容的提问来源于stack exchange,提问作者Ali Özen
相关产品推荐
相关产品推荐

