多文件上传Curl转PHP Guzzle报500错误,求验证转换正确性
问题:将Curl上传命令转为Guzzle实现时出现500错误,代码是否正确?
原Curl命令:
curl -X POST "https://uploadexample.net/api/upload" -H "accept: application/json" -H "Authorization: bearer: 928292992qwg" -H "Content-Type: multipart/form-data" -F "front_photo=@photo-1-214x300.jpg;type=image/jpeg" -F "back_photo=@photo-2-214x300.jpg;type=image/jpeg"
你写的错误代码:
$headers = [ 'Content-type' => 'application/json', 'Content-type' => 'multipart/form-data', 'Accept' => 'application/json', "Authorization" => "Bearer 928292992qwg" ]; $client = new Client([ // Base URI is used with relative requests 'base_uri' => 'https://exampleuploadrx.net', ]); $response = $client->request('POST', '/api/upload', [ 'json' => [ 'front_photo' => new CURLFile('photo-1-214x300.jpg;type=image/jpeg'), 'back_photo' => new CURLFile('photo-2-214x300.jpg;type=image/jpeg'), ], 'headers' => $headers, ] );
代码里的错误点:
- 重复且错误的Content-Type头:数组里重复定义了
Content-type,后一个会覆盖前一个,但更关键的是,Guzzle处理multipart请求时会自动生成带boundary的正确Content-Type头,手动设置反而会干扰逻辑;另外你错误添加了application/json的Content-Type,和文件上传的multipart格式完全冲突。 - 用错请求参数类型:原Curl是
multipart/form-data格式上传文件,你却用了Guzzle的json选项——这个选项是用来发送JSON格式请求体的,和文件上传完全不兼容,应该用multipart选项。 - CURLFile构造错误:
CURLFile的第一个参数是纯文件路径,不能带;type=image/jpeg,文件类型应该作为第二个参数传入,格式为new CURLFile($filePath, $mimeType)。 - Authorization头格式不符:原Curl里是
bearer: 928292992qwg,你的代码写成了Bearer 928292992qwg,少了冒号,可能导致认证失败。 - base_uri域名错误:原Curl的目标域名是
uploadexample.net,你写成了exampleuploadrx.net,请求发到错误服务器会直接引发500错误。
正确的Guzzle实现代码:
use GuzzleHttp\Client; use GuzzleHttp\Psr7\Utils; // 初始化客户端,域名和原Curl保持一致 $client = new Client([ 'base_uri' => 'https://uploadexample.net', ]); $response = $client->request('POST', '/api/upload', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'bearer: 928292992qwg' // 和原Curl格式完全匹配 ], // 使用multipart参数处理文件上传 'multipart' => [ [ 'name' => 'front_photo', 'contents' => Utils::tryFopen('photo-1-214x300.jpg', 'r'), 'filename' => 'photo-1-214x300.jpg', 'headers' => [ 'Content-Type' => 'image/jpeg' ] ], [ 'name' => 'back_photo', 'contents' => Utils::tryFopen('photo-2-214x300.jpg', 'r'), 'filename' => 'photo-2-214x300.jpg', 'headers' => [ 'Content-Type' => 'image/jpeg' ] ] ] ]); // 获取响应内容 $body = $response->getBody()->getContents();
如果习惯用CURLFile,也可以这么写:
use GuzzleHttp\Client; $client = new Client([ 'base_uri' => 'https://uploadexample.net', ]); $response = $client->request('POST', '/api/upload', [ 'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'bearer: 928292992qwg' ], 'multipart' => [ [ 'name' => 'front_photo', 'contents' => new \CURLFile('photo-1-214x300.jpg', 'image/jpeg') ], [ 'name' => 'back_photo', 'contents' => new \CURLFile('photo-2-214x300.jpg', 'image/jpeg') ] ] ]);
内容的提问来源于stack exchange,提问作者Bob Hijt





