Thursday 25 April 2019

Uploading multiple files/array of files through curl in php

Many might have run in to issues while trying to upload multiple files or sending multipart form data to server through curl . Ideally, to send multiple files, one would save the files to an array variable and pass it through curl. But this would end up in error "Array to string conversion in /path/to/upload.php"

This means you are trying to send the files as mentioned in the below code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

$user = "admin";

$postField = array();

$postFields['user'] = $user; //postdata

$postFields['upload_file'] = array(

        'file[0]' => '@' . realpath('first-file.jpg'),
        'file[1]' => '@' . realpath('second-file.jpg')
    )

$headers = array("Content-Type" => "multipart/form-data");
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, "http://serverdomain.com/upload/uploadMultipleFiles");
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_handle, CURLOPT_POST, TRUE);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);

$returned_data = curl_exec($curl_handle);
curl_close($curl_handle);
echo $returned_data ;
?> 


This is what should be the ideal code to send multiple files through php as per the manual, but pragmatically, it isn't right. You will not be able to send array of files through curl or technically, we can say, it won't support multi-dimensional arrays. Instead, you can send them as multiple CURL File objects
(PHP 5 >= 5.5.0, PHP 7) or single dimension array if you are using PHP <5. 

So the below code would help you send multiple files using CURL File object:




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

$user = "admin";

$postField = array();

$postFields['user'] = $user; //postdata

$postFields['upload_file_0'] = curl_file_create(
     realpath('first-file.jpg'), "mime", 'first-file.jpg' );

$postFields['upload_file_1'] = curl_file_create( 
     realpath('second-file.jpg'), "mime", 'second-file.jpg' );

$headers = array("Content-Type" => "multipart/form-data");
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, "http://serverdomain.com/upload/uploadMultipleFiles");
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_handle, CURLOPT_POST, TRUE);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);

$returned_data = curl_exec($curl_handle);
curl_close($curl_handle);
echo $returned_data ;
?>



If your version of php doesn't support CURL File objects, you can declare the array as

$postFields['upload_file_0'] = '@' . realpath('first-file.jpg');//@ is mandatory to send files

$postFields['upload_file_1'] = '@' . realpath('first-file.jpg');

In case of more than two files or some 'n' number of files you can use loop:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php

$user = "admin";
$fileName = array();
$tempFileName = array();

 

$filecount = count($_FILES['upload_file']['name']);
for($i=0; $i<$filecount; $i++){
$fileName[] = $_FILES["upload_file"]['name'][$i];
$tempFileName[] = $_FILES["upload_file"]['tmp_name'][$i];
} 

 $postField = array();

$postFields['user'] = $user; //postdata

foreach ($tempFileName as $index => $file) {
  if (function_exists('curl_file_create')) { // For PHP 5.5+
    $file = curl_file_create($file, "mime", $fileName[$index]);
  } else {
    $file = '@' . realpath($file);
  }
  $postFields["upload_file_$index"] = $file;
}

$headers = array("Content-Type" => "multipart/form-data");
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL,  
"http://serverdomain.com/upload/uploadMultipleFiles");
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl_handle, CURLOPT_POST, TRUE);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);

$returned_data = curl_exec($curl_handle);
curl_close($curl_handle);
echo $returned_data ;
?> 


Hope this helped you dig out a perfect solution!