Laravel使用File缓存驱动缓存HTTP响应时出现fseek错误
解决Laravel File缓存驱动缓存HTTP响应时的fseek错误
问题原因
Laravel HTTP Client返回的Illuminate\Http\Client\Response对象包含无法被序列化的流资源(用于处理响应体数据)。当使用File缓存驱动时,缓存系统会将对象序列化后写入文件,但流资源无法被正确序列化和反序列化。第二次从缓存读取时,原本的流资源会变成无效的int类型,触发fseek(): Argument #1 ($stream) must be of type resource, int given错误。
解决方案
不要直接缓存HTTP响应对象,而是缓存响应的可序列化数据(如JSON数组、响应内容字符串等),示例代码如下:
public function manufacturers(){ return Cache::remember('manufacturers', 10, function () { $response = Http::withoutVerifying()->post(config('api.systems').'Manufacturers/filter', [ 'showAll' => true ]); // 缓存响应的JSON数据(推荐,直接返回业务可用的数组) return $response->json(); // 若需要保留响应的完整信息(状态码、头等),可以存储结构化数组: // return [ // 'status_code' => $response->status(), // 'headers' => $response->headers()->all(), // 'data' => $response->json() // ]; }); }
如果业务场景必须使用响应对象的方法(如->ok()、->header()等),可以在读取缓存后重新构建响应对象:
public function manufacturers(){ $cachedData = Cache::remember('manufacturers', 10, function () { $response = Http::withoutVerifying()->post(config('api.systems').'Manufacturers/filter', [ 'showAll' => true ]); return [ 'status' => $response->status(), 'headers' => $response->headers()->all(), 'body' => $response->body() ]; }); // 重新构建响应对象 return Illuminate\Http\Client\Response::fromRawResponse( new GuzzleHttp\Psr7\Response( $cachedData['status'], $cachedData['headers'], $cachedData['body'] ) ); }
补充说明
其他缓存驱动(如Redis)能正常工作,是因为它们的序列化/存储机制对复杂对象的兼容性更好,但File驱动仅适合存储可被PHP原生序列化的简单数据类型(数组、字符串、基础类型等)。
内容的提问来源于stack exchange,提问作者David Milenkovic
相关产品推荐
相关产品推荐

