使用curl上传多个文件

7

如何使用CURLFilecurl_setopt上传多个文件到数组中?

使用data数组会出错(无法将数组转换为字符串),而对数据使用http_build_query会破坏CURLFile对象。

我要上传的数据看起来像这样:

[
    'mode' => 'combine',
    'input' => 'upload',
    'format' => $outputformat,
    'files' => [
        [0] => CURLFile object,
        [1] => CURLFile object,
        [x] => ...
    ]
]
3个回答

9

PHP 5.5+提供了一个不使用CURLFile来创建文件的函数: curl_file_create

您可以像这样上传多个文件:

<?php

$files = [
    '/var/file/something.txt',
    '/home/another_file.txt',
];

// Set postdata array
$postData = ['somevar' => 'hello'];

// Create array of files to post
foreach ($files as $index => $file) {
    $postData['file[' . $index . ']'] = curl_file_create(
        realpath($file),
        mime_content_type($file),
        basename($file)
    );
}

$request = curl_init('https://localhost/upload');
curl_setopt($request, CURLOPT_POST, true);
curl_setopt($request, CURLOPT_POSTFIELDS, $postData);
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($request);

if ($result === false) {
    error_log(curl_error($request));
}

curl_close($request);

这将作为一个数组在服务器上接收,位于file下面,就像有一个已发布的表单一样,这是$_FILES

Array
(
    [file] => Array
        (
            [name] => Array
                (
                    [0] => 1.txt
                    [1] => 2.txt
                )

            [type] => Array
                (
                    [0] => text/plain
                    [1] => text/plain
                )

            [tmp_name] => Array
                (
                    [0] => /private/var/folders/cq/7262ntt15mqdmylblg9p1wf80000gn/T/phpp8SsKD
                    [1] => /private/var/folders/cq/7262ntt15mqdmylblg9p1wf80000gn/T/php73ijEP
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 6
                    [1] => 6
                )

        )

)

这是$_POST
Array
(
    [somevar] => hello
)

1
问题在于服务器是一个API,文件必须放置在“files”数组中。 - Sébastien
他们希望文件是一个文件数组,就像你发布的数据一样,还是另一种格式的文件数组,例如文件内容的Base64编码字符串? - sjdaws
可以选择文件或base64,但对于大文件不建议使用后者选项。 - Sébastien
它不起作用。我的数组似乎格式良好(files [0] => CURLFile Object,files [1] => CURLFile Object,...),但是 curl_exec 运行直到超时... - Sébastien
无法工作。我尝试了很多次,但在这里面临着完全相同的挑战,即通过CURL将多个文件发送到API。 - Leandro Berg

4
索引是关键字的一部分。
[
    'mode' => 'combine',
    'input' => 'upload',
    'format' => $outputformat,
    'files[0]' => CURLFile object,
    'files[1]' => CURLFile object,
    'files[x]' => CURLFile object
     ...
    ]
]

1

我知道,这是一个老问题,但我也遇到了同样的问题。我没有找到cURL的解决方案,但是通过使用file_get_contents函数,我成功地解决了这个问题。 请注意,我对所有文件都使用相同的密钥

示例:

/* Prepare request */
$multipartBoundary = "--------------------------" . microtime(true);
$contentType = "multipart/form-data; boundary={$multipartBoundary}";
$content = "";

// Files
$paramName = "files";
foreach ($files as $file) {
    $fileBaseName = basename($file);
    $fileContent = file_get_contents($file);
    $content .= "--{$multipartBoundary}\r\n";
    $content .= "Content-Disposition: form-data; name=\"{$paramName}\"; filename=\"{$fileBaseName}\"\r\n";
    $content .= "Content-Type: application/zip\r\n\r\n{$fileContent}\r\n";
}

// Regular params
foreach ($params $key=>$value) {
    $content .= "--{$multipartBoundary}\r\n";
    $content .= "Content-Disposition: form-data; name=\"{$key}\"\r\n\r\n{$value}\r\n";
}

// End
$content .= "--{$multipartBoundary}--\r\n";

// Create context
$context = stream_context_create(['http' => [
    'header' => "Content-type: {$contentType}",
    'method'  => "POST",
    'timeout' => 5, // Seconds
    'content' => $content,
    'ignore_errors' => true // Do not report about HTTP errors as PHP Warnings
]]);



/* Send request */
$apiUrl = "https//api.example.com";
$endpoint = "/upload";
$url = $apiUrl . $endpoint;
$body = file_get_contents($url, false, $context);
$headerInfo = explode(" ", $http_response_header[0]);
$code = (int)$headerInfo[1];
$message = implode(" ", array_slice($headerInfo, 2));



/* Return result */
return [$body, $code, $message];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接