-1

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?

3
  • 1
    I recommend you to use this little tool incarnate.github.io/curl-to-php Commented Jun 28, 2022 at 15:30
  • Maybe look at http_build_query Commented Jun 28, 2022 at 15:30
  • @executable that's a really handy tool but unfortunately it produced code as ['colours[]'=>'red', 'yellow[]'=>'red' ] which isn't going to work. Plus file upload using @ prefix is no longer allowed in PHP Commented Jun 28, 2022 at 15:46

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @vee that looks like it would normally work. However I get an error response from the server 'Invalid parameter: 'colours' should be an array (use 'colours[]' instead)'. I've no idea what the server is written in. It's not ours.
It actually is the same with HTML form name="colours[]". If you tested with this HTML form and work, what I suggested should work. The number in indexed array should be start from zero and increase by one while in your question start from 1 and duplicated with 2.
0

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('/%5B[0-9]+%5D/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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.