Fluffy
Fluffy

Reputation: 28402

PHP curl resets content-length if CURLOPT_POST is set with curl_setopt_array?

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?

Upvotes: 2

Views: 6869

Answers (1)

Adam Hopkinson
Adam Hopkinson

Reputation: 28793

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.

Upvotes: 2

Related Questions