user926352
user926352

Reputation:

cURL not actually sending POST data

Overview
I have a script, we'll call it one.php, that creates a database and tables. It also contains an array of data to be posted to another script, two.php, which will sort through the data and insert it into our newly created database.

Your help is much, much appreciated.

The Problem
two.php has a check for the $_POST[] array at the very top of the script:

if (empty($_POST))
{
  $response = array('status' => 'fail', 'message' => 'empty post array');
  echo json_encode($response);
  exit;
}

Normally, this would not be triggered unless the post array is, well, empty(). However, when sending the data from one.php to two.php via cURL, I'm receiving the above encoded array as my response, and my data does not progress further down two.php.

I'll lay out the relevant code from the files below for your viewing pleasure:

one.php

$one_array = array('name' => 'John', 'fav_color' => 'red');
$one_url   = 'http://' . $_SERVER['HTTP_HOST'] . '/path/to/two.php';

$response = post_to_url($one_url, $one_array, 'application/json');
echo $response; die;

This is currently giving me the below:

{"status":"fail","message":"empty post array"}

The post_to_url() function, for reference

function post_to_url($url, $array, $content_type) 
{
  $fields = '';
  foreach($array as $key => $value) 
  { 
    $fields .= $key . '=' . $value . '&'; 
  }

  $fields = rtrim($fields, '&');

  $ch = curl_init();
  $httpheader = array(
    'Content-Type: ' . $content_type,
    'Accept: ' . $content_type
  );

  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);

  $result = curl_exec($ch);

  curl_close($ch);

  return $result;
}

two.php

header("Content-type: application/json");
$response = array(); //this is used to build the responses, like below

if (empty($_POST))
{
  $response['status']  = 'fail';
  $response['message'] = 'empty post array';
  echo json_encode($response);
  exit;
}
elseif (!empty($_POST))
{
  //do super neat stuff
}

Upvotes: 11

Views: 17389

Answers (2)

Manvel
Manvel

Reputation: 808

I have some issue like that, but in my case I added

Content-Type: {APPLICATION/TYPE}
Content-Length: {DATA LENGTH}

and problem was solved.

Upvotes: 0

Ja͢ck
Ja͢ck

Reputation: 173522

Because you're setting the request body content type as "application/json", PHP will not populate $_POST in "two.php". Because you're sending url encoded data, the best thing to do is only send the Accept: header:

curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: ' . $content_type]);

That said, "two.php" doesn't actually use the Accept: header and always outputs JSON; in that case, you can make do with not setting CURLOPT_HTTPHEADER at all.

Update

Creating url encoded data from an array can be simpler (and safer) too:

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));

Upvotes: 9

Related Questions