Home > Net >  PHP Curl array post fields including a file upload
PHP Curl array post fields including a file upload

Time:07-01

I need to do the following using PHP curl:

curl "https://the.url.com/upload"
  -F file="@path/to/the/file"
  -F colours[]="red"
  -F colours[]="yellow"
  -F colours[]="blue"

The code I have tried:

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
   'file' => curl_file_create($file),
   'colours' = ['red','yellow','blue']
]);
$response = curl_exec($ch);

But I just get an error 'Array to string conversion in... (the colours line)'. If I remove the colours entirely then it works but I need to include them.

I have tried putting the post fields array in http_build_query() but then the server returns '415 Unsupported Media Type'. I'm guessing because it's missing a mime type (the file is a custom binary file).

I have also tried...

'colours[1]' = 'red'
'colours[2]' = 'yellow'
'colours[2]' = 'blue'

But the server returns an error saying colours must be an array. It's as though I need to create an associative array but with duplicate keys... which I know I can't do.

Can anyone help?

CodePudding user response:

From the document of CURLOPT_POSTFIELDS.

This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data.

The function http_build_query() will make the value becomes 'para1=val1&para2=val2&...'.

So, I use this as post fields value as array and it work.

$postFields['hidden-input[0]'] = 'hidden value (from cURL).';

In your case, it should be.

curl_setopt($ch, CURLOPT_POSTFIELDS, [
   'file' => curl_file_create($file),
   'colours[0]' => 'red',
   'colours[1]' => 'yellow',
   'colours[2]' => 'blue',
]);

Related answered: 1.
The manual array (name[0]) copied from PHP document in Example #2 CURLFile::__construct() uploading multiple files example.

CodePudding user response:

While the answer from @vee should have worked, this came down to validation on this particular server application. After consulting with the vender, I ended up having to do this:

$headers = ['Content-type: multipart/form-data'];

$postFields = [
   // NEEDED TO INCLUDE THE MIME TYPE
   'file' => curl_file_create($file, mime_content_type($file)),
   'colours[]' => ['red', 'yellow', 'blue'],
];


// NEEDED TO REMOVE THE NUMBERS BETWEEN SQUARE BRACKETS
$postFieldString = preg_replace('/[[0-9] ]/simU', '', http_build_query($postFields));

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFieldString);
$response = curl_exec($ch);
  • Related