4

I am trying to pass a json data as param for cURL POST. However, I am stuck at grabbing it and saving it on db.

cURL file:

$data = array("name" => "Hagrid", "age" => "36");                                                                    
$data_string = json_encode($data);                                                                                   

$url = 'http://localhost/project/test_curl';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
                                    'Content-Type: application/json')                                                                                           
                                    );                       
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                                                                     

$result = curl_exec($ch);  

//based on http://www.lornajane.net/posts/2011/posting-json-data-with-php-curl

test_curl file:

    $order_info = $_POST; // this seems to not returning anything

    //SAVE TO DB... saving empty...

What did I miss? Weew....

5
  • As mentioned in your tutorial link you have to add the content length parameter as an additional header. I can ensure that this tutorial totally works (I used it for myself 2 days ago). If that does not work maybe the designed target of the curl request does not have the expected behaviour. Commented Jan 30, 2012 at 10:03
  • By the way, CURLOPT_POSTFIELDS need an associative array to post, like array('data' => $data_string) otherwise it won't post anything Commented Jan 30, 2012 at 10:06
  • @DieVarDump That is not true. It accepts a string or an associative array. If you want to use Content-Type: application/json it must be a string. It is better to create the string yourself and pass that, because if you pass an array the Content-Type will be multipart/form-data and the request body will likely be much larger than it would be if you use application/x-www-form-urlencoded. Commented Jan 30, 2012 at 10:08
  • @DaveRandom yes, my mistake, i didn't see the HTTPHEADER... forget about my previous comment. Commented Jan 30, 2012 at 10:15
  • @TRD Yes... I just got confused on handling JSON post and just mentioned in my question where I get my example. Just sayin' there is no problem with the tutorial... it's me having a problem grasping it. :) Thanks man! Commented Jan 30, 2012 at 10:17

2 Answers 2

20

You are sending the data as raw JSON in the body, it will not populate the $_POST variable.

You need to do one of two things:

  1. You can change the content type to one that will populate the $_POST array
  2. You can read the raw body data.

I would recommend option two if you have control over both ends of the communication, as it will keep the request body size to a minimum and save bandwidth over time. (Edit: I didn't really emphasize here that the amount of bandwidth it will save is negligible, only a few bytes per request, this would only be a valid concern is very high traffic environments. However I still recommend option two because it is the cleanest way)

In your test_curl file, do this:

$fp = fopen('php://input', 'r');
$rawData = stream_get_contents($fp);

$postedJson = json_decode($rawData);

var_dump($postedJson);

If you want to populate the $_POST variable, you will need to change the way you send the data to the server:

$data = array (
  'name' => 'Hagrid',
  'age' => '36'
);

$bodyData = array (
  'json' => json_encode($data)
);
$bodyStr = http_build_query($bodyData);

$url = 'http://localhost/project/test_curl';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  'Content-Type: application/x-www-form-urlencoded',
  'Content-Length: '.strlen($bodyStr)
));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyStr);

$result = curl_exec($ch);

The raw, undecoded JSON will now be available in $_POST['json'].

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

7 Comments

I did option two. Thank you very much! It worked and you did explain it well... wooow I did miss a lot. Again, thanks!
thx for this details, Does the GET works the same with those 2 content types?
@ciril A GET request has no content, and therefore no content-type. If you wan't to pass JSON via GET (which I don't recommend, by the way) you need to append it to the URL. For example $url = 'http://example.com/script.php?json='.urlencode(json_encode($data)); - the data will then be available in $_GET['json'] at the other end.
right, so I can also remove in my code curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeader); when performing a get probably, thx
If all the headers are related to content, probably yes. Although to be honest I think cURL is pretty intelligent when it comes to inspecting the headers before use - I doubt it would break if you leave them in.
|
0

Use following php function for posting data using php curl function in x-www-form-urlencoded format.

<?php
    $bodyData = http_build_query($data); //for x-www-form-urlencoded
?>

1 Comment

Please be careful with linking to your own content on different sites, you don't want to be a spammer. You should be including the majority of the content here, and use the link only as a reference.

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.