php 通过CURLOPT_POSTFIELDS向curl发布多个文件

mnemlml8  于 2023-08-02  发布在  PHP
关注(0)|答案(2)|浏览(201)

我有一个API,我试图使用,接受多个文件在一个单一的HTTP POST通过multipart形式的数据。
问题是,这些文件具有相同的密钥(images)。在Postman中,示例请求如下所示:

的数据
在cURL中也是这样:

curl --location 'http://my-amazing-service.local' \
--form 'images=@"/Users/zach/Desktop/1.jpg"' \
--form 'images=@"/Users/zach/Desktop/2.jpg"' \
--form 'images=@"/Users/zach/Desktop/3.jpg"'

字符串
问题出在PHP中,CURLOPT_POSTFIELDSdoes not take multidimensional arrays。不管出于什么原因,它在我的Mac上工作,但在运行Alpine Linux的Docker容器中不行。
当我在Alpine Linux(在Docker容器中)上运行下面的代码时,我可以从头文件中的Content-Length中看到只有146,这意味着没有包含映像的二进制内容(我的测试映像大约50KB)。
可以将多个文件传递到CURLOPT_POSTFIELDS中吗?如果可能的话,我宁愿不用手动编写原始的多部分POST正文。

$curl = curl_init();
      
curl_setopt_array($curl, array(
    CURLOPT_URL => 'http://my-amazing-service.local',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_POSTFIELDS => [
        'images' => [
            file_get_contents('1.jpg'),
            file_get_contents('2.jpg'),
            file_get_contents('3.jpg'),
        ],
    ]
));
$verbose = fopen('php://temp', 'w+');
curl_setopt($curl, CURLOPT_STDERR, $verbose);
curl_setopt($curl, CURLOPT_VERBOSE, true);
$response = curl_exec($curl);
if ($response === FALSE) {
    printf("cURL error: %s\n", curl_error($curl));
}
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", $verboseLog, "</pre>\n";        
curl_close($curl);

c0vxltue

c0vxltue1#

您可以使用函数curl_file_create根据您的请求附加多个文件,例如:

$file1 = curl_file_create('1.jpg');
$file2 = curl_file_create('2.jpg');

$data = array(
  'file1' => $file1,
  'file2' => $file2
);

$ch = curl_init('https://example.com/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

字符串
使用您的方法:

$curl = curl_init();
      
curl_setopt_array($curl, array(
    CURLOPT_URL => 'http://my-amazing-service.local',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_POSTFIELDS => [
        'file1'  => curl_file_create('1.jpg'),
        'file2' => curl_file_create('2.jpg'),
        'file3' => curl_file_create('3.jpg'),
    ]
));

$response = curl_exec($curl);


为了在CURLOPT_POSTFIELDS上使用单个key,您必须使用与在查询字符串中传递数组相同的语法:

curl_setopt_array($curl, array(
    CURLOPT_URL => 'http://my-amazing-service.local',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_POSTFIELDS => [
        'files[0]'  => curl_file_create('1.jpg'),
        'files[1]' => curl_file_create('2.jpg'),
        'files[2]' => curl_file_create('3.jpg'),
    ]
));


这与我们在查询字符串上传递一个值数组时使用的语法相同:

http://example.com?name[0]=jon&name[1]=ari&name[2]=alex

0md85ypi

0md85ypi2#

经过进一步检查,看起来很难在同一字段名称中发送一堆文件的原因是因为它在技术上违反了RFC 2388
在表单中,有一系列由填写表单的用户提供的字段。每个字段都有一个名称。在给定的表单中,名称是唯一的。
所以这个问题从“我能做吗?”变成“我应该做吗?“
我认为更好的解决方案是联系API维护者并提出这个问题。

相关问题