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

如何在PHP CURL的POST字段中为key指定Content-Type?

对接含JSON类型字段的文件上传API返回400 Bad Request问题

我需要对接一个支持文件上传且包含JSON类型字段fileMetadata的API。对应的CURL命令中,fileMetadata字段需指定type=application/json;在Postman中设置该字段的Content-Type为JSON后,请求才能被API接受。

我编写了PHP代码实现对接:先从FTP下载文件到本地临时目录,通过curl_file_create创建文件对象,将fileMetadata字段JSON编码后加入POST参数,使用第三方函数处理POST字段避免“Array to string conversion”错误,但API仍返回400 Bad Request。经测试,怀疑是fileMetadata字段的Content-Type未被正确识别(Postman中不设置该类型时会返回相同错误)。

相关代码及CURL请求信息如下:

上传逻辑代码

$headers = array(
    'X-AUTH-TOKEN: ' . config('services.camera.X-AUTH-TOKEN'),
    'X-upload-Type: batch'
);
$body = [];
$local = Storage::disk('public');
foreach($images as $key => $img){
    //从远程FTP下载文件并存入临时文件(用于CURL上传)
    $local->put(".temp/" . $img['fileName'], Storage::disk("ftp")->get("new/" . $img['fileName']));
    $path = $local->path('.temp/' . $img['fileName']);
    //创建CURL文件对象
    $body['file'][$key] = curl_file_create($path, mime_content_type($path), basename($path));
}
//对文件数组详情进行JSON编码
$body["fileMetadata"] = json_encode($images);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, config('services.camera.url') . $batchId);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->build_post_fields($body));
$result = curl_exec($ch);
curl_close($ch);
$local->deleteDirectory('.temp');
dd($result);

CURL请求信息

"url" => "HIDDEN"
"content_type" => "application/json"
"http_code" => 400
"header_size" => 296
"request_size" => 294
"filetime" => -1
"ssl_verify_result" => 0
"redirect_count" => 0
"total_time" => 0.525641
"namelookup_time" => 0.075162
"connect_time" => 0.153136
"pretransfer_time" => 0.260049
"size_upload" => 760.0
"size_download" => 151.0
"speed_download" => 287.0
"speed_upload" => 1445.0
"download_content_length" => -1.0
"upload_content_length" => 760.0
"starttransfer_time" => 0.260055
"redirect_time" => 0.0
"redirect_url" => ""
"primary_ip" => "HIDDEN"
"certinfo" => []
"primary_port" => 443
"local_ip" => "HIDDEN"
"local_port" => 56168
"http_version" => 3
"protocol" => 2
"ssl_verifyresult" => 0
"scheme" => "HTTPS"
"appconnect_time_us" => 259936
"connect_time_us" => 153136
"namelookup_time_us" => 75162
"pretransfer_time_us" => 260049
"redirect_time_us" => 0
"starttransfer_time_us" => 260055
"total_time_us" => 525641

调用上传函数的代码

try {
    $files = Storage::disk('ftp')->files("/new");
    $unique_devices = [];
    foreach($files as $file){
        //拆分文件名以获取所需API信息
        $break = explode("+", $file);
        $device_id = str_replace("new/", "", $break[0]); //设备ID
        if(!isset($break[1])){
            continue;
        }
        if(!in_array($device_id, $unique_devices)){
            //API要求每个设备生成一个批次,此处收集唯一设备ID
            array_push($unique_devices, $device_id);
            $this->info[$device_id]["fileMetadata"] = [];
        }
        //拆分其他关键信息
        $file_name = str_replace("new/", "", $file);
        $dateBreakDown = explode(".", $break[1]);
        $date = explode("_", $dateBreakDown[0]);
        $time = $date[1] . $date[2] . $date[3];
        $date = str_replace("-", "", $date[0]);
        //将信息加入数组(对应上传函数的$images变量)
        array_push($this->info[$device_id]["fileMetadata"], ["fileName" => $file_name, "deviceId" => "D-TR-0010"/*$device_id*/, "date" => $date, "time" => $time]);
    }
    $batches = $this->genBatchId($unique_devices);
    foreach($this->info as $dId => $upload){
        $this->uploadFiles($upload['fileMetadata'], $batches[$dId]);
    }
} catch (Exception $e){
    Log::debug($e->getMessage());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:43:07