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

使用Guzzle上传大文件失败的问题排查与解决

修复方案

1. 移除错误的Content-Type请求头

Guzzle处理MULTIPART类型请求时,会自动生成正确的multipart/form-data请求头,手动设置的application/json会导致请求格式冲突,这是大文件上传失败的核心原因。修改Client初始化代码:

$apiClient = new Client([
    'base_uri' => $url,
    'timeout'  => 30, // 大文件上传需更长超时时间,原5秒不足以完成上传
    'headers' => [
        'Accept'     => 'application/json', // 仅保留Accept头即可
    ],
]);

2. 简化文件流处理

无需手动通过Psr7\Utils::streamFor包装文件流,直接传递文件路径或fopen资源给contents即可,Guzzle会自动处理为流式上传:

$postParams = [
    RequestOptions::MULTIPART => [
        ...$multipartParams,
        [                        
            'name' => 'upload',
            'contents' => $filePath, // 直接传文件路径,更简洁
            'filename' => $postFields['filename'],
        ]
    ]
];

也可以保留fopen方式:

'contents' => fopen($filePath, 'r'),

3. 调整超时时间

大文件上传需要更多传输时间,原5秒超时会导致上传中途中断,将timeout调整为30秒以上,具体数值可根据文件大小和网络情况调整。


调试定位方法

1. 捕获Guzzle具体错误信息

当前错误栈仅展示调用链,无具体错误原因,通过捕获GuzzleException可获取详细错误:

use GuzzleHttp\Exception\GuzzleException;

try {
    $response = $apiClient->post("upload", $postParams);
} catch (GuzzleException $e) {
    echo "错误详情:" . $e->getMessage() . "\n";
    echo "CURL错误码:" . $e->getCode() . "\n";
    // 调试时可输出请求和响应详情
    echo "请求信息:" . $e->getRequest()->getMethod() . " " . $e->getRequest()->getUri() . "\n";
    if ($e->hasResponse()) {
        echo "响应状态码:" . $e->getResponse()->getStatusCode() . "\n";
        echo "响应内容:" . $e->getResponse()->getBody()->getContents() . "\n";
    }
}

2. 对比Guzzle请求与curl命令的差异

将Guzzle生成的请求转化为curl命令,与本地正常工作的curl命令对比,可快速定位请求头、超时等配置差异:

// 添加中间件输出Guzzle生成的请求详情
$handlerStack = \GuzzleHttp\HandlerStack::create();
$handlerStack->push(\GuzzleHttp\Middleware::tap(function ($request) {
    echo "Guzzle请求详情:\n" . \GuzzleHttp\Psr7\Message::toString($request) . "\n";
}));

$apiClient = new Client([
    'base_uri' => $url,
    'timeout'  => 30,
    'handler' => $handlerStack,
    'headers' => [
        'Accept'     => 'application/json',
    ],
]);

3. 检查PHP与curl配置

  • 确认PHP的upload_max_filesize和post_max_size配置(客户端上传时,这些配置可能影响流处理逻辑)
  • 检查curl是否有限速设置,可手动关闭限速:
$apiClient = new Client([
    'base_uri' => $url,
    'timeout'  => 30,
    'headers' => [
        'Accept'     => 'application/json',
    ],
    'curl' => [
        CURLOPT_MAX_SEND_SPEED_LARGE => 0, // 关闭curl限速
    ],
]);

内容的提问来源于stack exchange,提问作者WeSee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:37:01