You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:45:56