Send array as json and read that data - php

I am encoding array as json and sending it by curl to other file:
$data = array(
"authorizedKey" => "abbad35c5c01-xxxx-xxx",
"senderEmail" => "myemail#yahoo.com",
"recipientEmail" => "jaketalledo86#yahoo.com",
"comment" => "Invitation",
"forceDebitCard" => "false"
);
$data = json_encode($data);
$ch = curl_init('http://localhost/curl/1.php');
$headers = array('Accept: application/json','Content-Type: application/json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
echo curl_exec($ch);
curl_close($ch);
Problem is http://localhost/curl/1.php dont recieve any $_POST and I dont know how to operate on posted data.
http://localhost/curl/1.php output:
Headers:
Host = localhost
Accept = application/json
Content-Type = application/json
Content-Length = 166
GET:
empty
POST:
empty

You are sending data by using request body, and you are supposed to get data by request body not $_POST super global. You can use following code to get whole data.
$entityBody = file_get_contents('php://input');

If you want the data to show up in $_POST, don't encode it as JSON. Just pass the $data array to the CURLOPT_POSTFIELDS option, and don't send the Content-type: application/json header. cURL will then use the normal encoding for POST data, which PHP can convert into fields in the $_POST variable.

Related

PHP Curl Send JSON Data

I am following this tutorial:
https://lornajane.net/posts/2011/posting-json-data-with-php-curl
what I am trying to do is POST JSON Data through CURL
$url = "http://localhost/test/test1.php";
$data = array("name" => "Hagrid", "age" => "36");
$data_string = json_encode($data);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,array("Content-type: application/json", "Content-Length: " . strlen($data_string)));
$result = curl_exec($ch);
var_dump($result);
when I POST plain text data , I am able to receive that, but when I try through JSON , I am not able to receive that.
Here is my test1.php
test1.php
print_r($_POST);
print_r($_POST);
Any help would be appreciated.
Thanks
When you POST JSON Data through cURL, you have to use php://input. You can use it like:
// get the raw POST data
$rawData = file_get_contents("php://input");
// this returns null if not valid json
return json_decode($rawData, true); // will return array
php://input is a read-only stream that allows you to read raw data
from the request body
The PHP superglobal $_POST, only is supposed to wrap data that is either
application/x-www-form-urlencoded (standard content type for simple form-posts) or
multipart/form-data-encoded (mostly used for file uploads)
The content would now be application/json (or at least none of the above mentioned), so PHP's $_POST -wrapper doesn't know how to handle that (yet).
Reference
JSON data does not come through in $_POST. You need to use file_get_contents('php://input');
You will also need to json_decode it.
$json = json_decode(file_get_contents('php://input'));
var_dump($json);

Convert URL encoded to JSON object

I've never worked with JSON objects before but I think this is probably the best route for what I'm trying to achieve (if you think there is a better option please let me know, though I cannot use SOAP)
I am trying to submit some data via POST to an API in order to add some data to a newsletter list which is stored as XML. Here is the documentation for the request I am trying to complete: https://api.dotmailer.com/v2/help/wadl#PostAddressBookContacts
When visiting the API url and authenticating I see data laid out in the following:
<ArrayOfApiContact xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://apiconnector.com">
<ApiContact>
<Id>1058905201</Id>
<Email>email#email.co.uk</Email>
<OptInType>Unknown</OptInType>
<EmailType>Html</EmailType>
<DataFields i:nil="true"/>
<Status>Subscribed</Status>
</ApiContact>
</ArrayOfApiContact>
So I have attempted to replicate as such, using a variable instead of a hardcoded email:
$xml = array(
'id' => urlencode('123456789'),
'email' => urlencode($useremail),
'optInType' => urlencode('Unknown'),
'emailType' => urlencode('Html'),
'dataFields' => urlencode(':null'),
'status' => urlencode('Subscribed')
);
I am combining the array here:
foreach($xml as $key=>$value) { $xml_string .= $key.'='.$value.'&'; }
And then using cURL to POST the request to the API, with my authentication (apipassword and apiemail which the username)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$auth_url);
curl_setopt($ch,CURLOPT_POST, count($xml));
curl_setopt($ch,CURLOPT_POSTFIELDS, $xml_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$apiemail:$apipassword");
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
$result = curl_exec ($ch);
curl_close ($ch);
I have already tested this without the POST and I do indeed get the data back in this form:
[{"id":1058905201,"email":"email#email.co.uk","optInType":"Unknown","emailType":"Html","dataFields":null,"status":"Subscribed"}]
So I know the auth is working and the data is coming back correctly, but now when I try to POST my data I get:
{"message":"Content type \"application/x-www-form-urlencoded\" is not supported. Please use one of: application/json,application/xml ERROR_CONTENT_TYPE_IS_NOT_SUPPORTED"}
So how do I convert my array which is URL encoded into something readable by the API?
Try a content type of application/json like so:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('content-type: application/json'));
Two things here (a) content-type header JSON missing and (b) payload not JSON.
// setup request to send json via POST.
$payload = json_encode(array("json"=> $data)); // or json_encode(array($data));
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
// set proper content-type for sending JSON
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

How to send and receive data to/from an API using CURL?

I have to make an API. For this, I will receive the data from the mobile devices as JSON using POST. I have to work with this data and send the response back to the devices also as JSON.
But I don't know how to take the data that I will receive. I have tried to make some tests using CURL to see how can I take this data but the $_POST is always empty. Can you please tell me how to send the data as JSON format to the API using CURL and how can I receive this data so I can work with it and send it back as response?
These are my test files:
curl.php:
//set POST variables
$url = 'http://test.dev/test.php';
$data = array(
'fname' => 'Test',
'lname' => 'TestL',
'test' => array(
'first' => 'TestFirst',
'second' => 'TestSecond'
)
);
//open connection
$ch = curl_init($url);
$json_data = json_encode($data);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($json_data))
);
// execute post
$result = curl_exec($ch);
echo $result;
//close connection
curl_close($ch);
test.php:
var_dump($_POST);
The response that I get is:
array(0) { }
You need to pass the POST data as a URL query string or as an array, the problem is you post data in JSON format, but PHP does not parse JSON automatically, so the $_POST array is empty. If you want it, you need do the parsing yourself in the test.php:
$raw_post = file_get_contents("php://input");
$data = json_decode($raw_post, true);
print_r($data);
same questions: 1 2

PHP cURL Content-Length and Content-Type wrong

I'm trying to login to a site via PHP cURL and I'm only getting "Bad Request" responses.
I played around with hosts file and set it to my server to check which Request Headers my browser sends and compare it to the request headers sent by cURL.
Everything is equal, except of:
Browser:
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
PHP cURL:
Content-Length: 51, 359
Content-Type: application/x-www-form-urlencoded; boundary=----------------------------5a377b7e6ba7
I already set that values with this command, but it still sends the wrong headers:
curl_setopt($this->hCurl, CURLOPT_HTTPHEADER, array(
'Expect:',
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: 51'
));
You shouldn't have to set the content-length yourself. If you use cURL to send an HTTP POST, it will calculate the content length for you.
If you set the CURLOPT_POSTFIELDS value as an array, it will automatically submit the request as multipart/form-data and use a boundary. If you pass a string, it will use application/x-www-form-urlencoded so make sure you pass a urlencoded string to CURLOPT_POSTFIELDS and not an array since you want form-urlencoded.
You need to be doing this:
$data = 'name=' . urlencode($value) . '&name2=' . urlencode($value2);
curl_setopt($this->hCurl, CURLOPT_POSTFIELDS, $data);
// NOT
$dataArray = array('name' => 'value', 'name2' => 'value2');
curl_setopt($this->hCurl, CURLOPT_POSTFIELDS, $dataArray);
In either case, you do not need to set the content length, but you have to use the first method to get application/x-www-form-urlencoded encoding on the form.
If that doesn't help, post all the code relevant to setting up the curl request, (all the options, and data you are passing to it) and that should help solve the problem.
EDIT:
Added is an example I came up with that works (I get failed login).
<?php
$URL_HOME = 'http://ilocalis.com/';
$LOGIN_URL = 'https://ilocalis.com/login.php';
$ch = curl_init($URL_HOME);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$home = curl_exec($ch);
//echo $home;
$post = array('username' => 'drew', 'password' => 'testing 123');
$query = http_build_query($post);
curl_setopt($ch, CURLOPT_URL, $LOGIN_URL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
$login = curl_exec($ch);
echo $login;

Type of "application/json" prevents post variables from being sent

I've found that if I try a PHP POST curl, the postvars are sent fine. Once I add the httpheader of content-type: application/json the postvars don't go across any more. I've tried the postvars as a JSON string and as a query string.
Showing some code:
$ch = curl_init();
$post = json_encode(array('p1' => 'blahblahblah', 'p2' => json_encode(array(4,5,6))));
$arr = array();
array_push($arr, 'Content-Type: application/json; charset=utf-8');
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr);
curl_setopt($ch, CURLOPT_URL, 'https://example.com/file.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_exec($ch);
curl_close($ch);
A real HTTP Post, that gets broken into an array automagically by PHP must be formatted in name=value pairs, the best way to do this in PHP is using the http_build_query function.
http://ca2.php.net/manual/en/function.http-build-query.php
There is an example that works in the PHP Manual using curl:
http://ca2.php.net/manual/en/function.curl-exec.php#98628
What you're doing is a 'RAW' post, see this other question:
How to post JSON to PHP with curl
A quick snippet to get the RAW Json data.
<?php
print_r(json_decode(file_get_contents('php://input')));

Categories