laravel缓存懒加载有四种方法:一、用lazycollection包装查询结果实现惰性迭代;二、repository模式延迟触发缓存读取;三、__invoke魔术方法构建可懒执行的缓存代理;四、结合streamedresponse实现http层边读边响应。

如果您在 Laravel 应用中面临高频缓存读取但部分数据实际未被使用的问题,则可能因过早加载缓存导致内存浪费或响应延迟。以下是实现缓存懒加载机制的多种方法:
一、使用 LazyCollection 包装缓存查询结果
该方法适用于从数据库批量读取后需按需消费的场景,避免一次性将全部缓存项载入内存,而是通过惰性迭代器逐条解析。
1、在服务类中定义缓存键并构造 LazyCollection:
2、调用 Cache::get() 获取原始缓存值(如序列化数组或 JSON 字符串)。
3、使用 LazyCollection::make() 包裹反序列化后的数据流,例如:LazyCollection::make(fn() => yield from json_decode($cachedJson, associative: true))。
4、后续链式调用 filter()、map() 或 take() 时均不立即执行,仅在 each() 或 all() 触发时才真实迭代。
二、基于 Repository 模式延迟触发缓存读取
该方法将缓存获取逻辑封装进资源库方法内部,确保仅当业务代码真正调用 get() 或 first() 时才访问缓存驱动,避免构造对象即加载。
1、在 PostRepo 类中定义私有属性 $cacheKey = 'posts_active_list',不初始化缓存值。
2、在 getById() 方法中不预加载全部缓存,而是在方法体内首次需要时执行 Cache::get($this->cacheKey)。
3、若缓存缺失,再调用底层模型查询并写入 Cache::put($this->cacheKey, $result, 3600)。
4、对外暴露的 public 方法保持签名不变,调用方无感知延迟行为。
三、利用 PHP 的 __invoke 魔术方法构建可懒执行的缓存代理
该方法创建一个轻量级代理对象,在其被当作函数调用时才真正读取缓存,适合注入到控制器或服务中作为延迟求值句柄。
1、新建类 CacheLazyProxy 并实现 __invoke() 方法。
2、构造函数接收缓存键与默认生成闭包,但不执行闭包。
3、在 __invoke() 中判断是否已缓存,若无则执行闭包并将结果存入 Cache,最后返回值。
4、在控制器中绑定为单例,并通过 $proxy = app(CacheLazyProxy::class)->withKey('user_stats')->withFallback(fn() => DB::table(...)->get()) 初始化。
5、仅当代码显式调用 $proxy() 时才触发实际缓存读写流程。
四、结合响应流(Response Streaming)实现 HTTP 层缓存懒加载
该方法适用于导出大量缓存数据的接口,避免将整个缓存集合加载进内存再输出,而是边读缓存边写响应流。
1、使用 Illuminate\Http\StreamedResponse 构造响应对象。
2、在回调函数中创建 LazyCollection 实例,其数据源为 Cache::get() 返回的可迭代结构(如 Redis SCAN 结果流或分块缓存键列表)。
3、对每个缓存项调用 yield,确保每处理一条即 flush 到客户端。
4、关键控制点:设置 Cache::store('redis')->scan(0, 'cache:export:*', 100) 分批获取键名,再逐个 fetch 值,全程不持有全部数据。











