Symfony HttpClient下载大文件出现Body size limit exceeded如何解决
问题原因
你遇到的Body size limit exceeded报错和php.ini配置无关,是Symfony HttpClient组件默认设置了16MB的响应体最大大小限制,你拉取的242MB文件远超过该阈值,因此触发异常。
解决方案
只需要在实例化HttpClient时自定义max_body_size参数即可解除限制,同时可搭配超时配置、异常判断逻辑保证下载稳定:
- 实例化HttpClient时添加配置
设置max_body_size为0即可取消响应体大小限制,也可按你的需求设置为固定值(比如314572800对应300MB),同时可延长超时时间适配大文件下载场景。 - 流下载过程增加异常判断
避免请求错误时写入无效内容。
修改后的完整代码如下:
public function infoBDD(): Response { // 实例化HttpClient时配置大小限制和超时 $httpClient = HttpClient::create([ 'max_body_size' => 0, // 取消响应体大小限制 'timeout' => 300, // 超时时间设为5分钟,可根据网络情况调整 ]); $response = $httpClient->request('GET', 'https://mtgjson.com/api/v5/AllPrintings.json'); // 建议使用项目根目录拼接绝对路径,避免相对路径出错 // 控制器内可注入KernelInterface,通过$kernel->getProjectDir()获取根目录 $filePath = '../public/BDD/Api.json'; $fileHandler = fopen($filePath, 'w'); if (!$fileHandler) { throw new \Exception('文件创建失败,请检查目录权限'); } // 流式写入增加异常判断 foreach ($httpClient->stream($response) as $chunk) { if ($chunk->isFirst()) { // 提前校验请求是否成功 if (200 !== $response->getStatusCode()) { fclose($fileHandler); unlink($filePath); throw new ServiceUnavailableHttpException('API请求失败,状态码:'.$response->getStatusCode()); } } if (!$chunk->isError()) { fwrite($fileHandler, $chunk->getContent()); } } fclose($fileHandler); $content = file_get_contents($filePath); $data = json_decode($content, true); if(!array_key_exists('data', $data)) { throw new ServiceUnavailableHttpException("La clé 'data' n'existe pas dans le tableau de données récupéré, la réponse type fournie par l'API a peut-être été modifiée"); } $api = $data['data']; $this->getTableauData($api); unlink($filePath); return $this->render('users/index.html.twig', [ 'controller_name' => 'UsersController', 'page' => 'Profile' ]); }
可选优化
你当前逻辑会将整个242MB的JSON文件全部加载到内存做解析,内存占用会是源文件的3-5倍,若要降低内存消耗,可以使用流式JSON解析工具边下载边解析数据,无需落地临时文件,也无需将完整JSON加载到内存。
内容的提问来源于stack exchange,提问作者Math86
相关产品推荐
相关产品推荐

