Reputation: 1697
How do I upload multiple files in an array using CURLFile
and curl_setopt
?
Using the data array as it would throw an error (can't convert an array to a string) and http_build_query
on the data would corrupt the CURLFile
objects.
The data I have to upload looks like that:
[
'mode' => 'combine',
'input' => 'upload',
'format' => $outputformat,
'files' => [
[0] => CURLFile object,
[1] => CURLFile object,
[x] => ...
]
]
Upvotes: 7
Views: 12422
Reputation: 61
The index is part of the key
[
'mode' => 'combine',
'input' => 'upload',
'format' => $outputformat,
'files[0]' => CURLFile object,
'files[1]' => CURLFile object,
'files[x]' => CURLFile object
...
]
]
Upvotes: 5
Reputation: 130
I know, this is the old questions but I faced the same problem as well. I haven't found solution for cURL but was able to solve the problem using file_get_contents. Note that I use the same key for all of the files.
Example:
/* 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];
Upvotes: 2
Reputation: 3536
PHP 5.5+ has a function to create files without using CURLFile: curl_file_create
.
You can upload multiple files like this:
<?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);
This will be received on the server as an array under file
the same as if there was a posted form, this is $_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
)
)
)
This is $_POST
:
Array
(
[somevar] => hello
)
Upvotes: 9