2

It looks like curl_setopt_array is different from just multiple invocations of curl_setopt. Consider this script:

$ch = curl_init('http://www.stackoverflow.com/'); [options] curl_exec($ch); var_dump(curl_getinfo($ch)); 

Now it sends a proper request if [options] are one of these:

curl_setopt_array($ch, array( CURLOPT_POST => true, CURLOPT_POSTFIELDS => array('a' => 'b'), )); 

or

curl_setopt_array($ch, array( CURLOPT_POSTFIELDS => array('a' => 'b'), )); 

or

curl_setopt($ch, CURLOPT_POSTFIELDS, 'a=b'); curl_setopt($ch, CURLOPT_POST, 1); 

BUT NOT this way:

curl_setopt_array($ch, array( CURLOPT_POSTFIELDS => array('a' => 'b'), CURLOPT_POST => true, )); 

It seems that the content-length is reset if CURLOPT_POST is set after CURLOPT_POSTFIELDS. Except it works ok if set with curl_setopt instead of curl_setopt_array.

Why is this?

1
  • Excellent work tracking this down. Now I can stop banging my head against the wall and upload photos through Facebook's API. Commented Feb 10, 2012 at 0:27

1 Answer 1

2

When you specify CURLOPT_POST, the post is sent as application/x-www-form-urlencoded.

But, from the curl_setopt manual page:

Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data, while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.

So when you do

curl_setopt_array($ch, array( CURLOPT_POSTFIELDS => array('a' => 'b'), // multipart/form-data CURLOPT_POST => true, // application/x-www-form-urlencoded )); 

The data is being set as mulpart/form-data (by setting CURLOPT_POSTFIELDS to an array) and then reset as application/x-www-form-urlencoded (by setting CURLOPT_POST to true).

The other examples work because you're not changing the type once the data is set.

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

3 Comments

but when I do the same with curl_setopt (last example), why does it work?
because both options set the type to application/x-www-form-urlencoded, so the data is not lost
Oh, I see, my bad. At this point I think that it is better to just omit CURLOPT_POST at all, the data type will be set based on post fields. Is that correct?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.