Cant get response from API using cURL in php - php

I'm trying to get response from API - I have to send an xml document, and then I should get another xml as an response, but all I got is 'xml error no element found'....
Here is my cURL code in php:
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'email=' . $email . '&password=' . $password . '&content=' . $xml);
$ex = curl_exec($ch);
Unfortunatelly, when I'm trying to echo $ex - the above error is shown.
All of my variables are correct, so does my xml (document is given in $xml variable).
What am I missing?

You are setting Content-Type header to text/xml, but actually you are trying to send the data as application/x-www-form-urlencoded. Either correct the header, or only send the $xml variable.
For example:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'Content-Length: '. strlen($xml))
);
$result = curl_exec($ch);
The CURLOPT_RETURNTRANSFER is purely so that the response from the remote server gets placed in $result rather than echoed.

Related

How to Retrieve cURL Data within the URL Endpoint

I am trying to create a cURL api, let's say the below is my curl request code, where http://localhost/api/endpoint.php is my endpoint. What would actually be going on, code-wise in the endpoint.php file? How do I actually get the data that is sent via the cURL request, like the CURLOPT_USERPWD data, in the endpoint.php page? Thanks.
$ch = curl_init();
$url = 'http://localhost/api/endpoint.php';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERPWD, 'alex:password123');
$headers = array(
'Accept: application/json',
'Content-Type: application/x-www-form-urlencoded',
'Accept-Language: en_US'
);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$vars['grant_type'] = 'client_credentials';
$req = http_build_query($vars);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
$response = curl_exec($ch);
You can access to these data via the $_SERVER superglobal.
Endpoint :
<?php
$user = $_SERVER['PHP_AUTH_USER']; // alex
$password = $_SERVER['PHP_AUTH_PW']; // password123
in your file endpoint.php you can print your posted value using
print_r($_POST);
after your curl print response like
print_r($response);

PHP cURL how to send a JSON POST request and also include a URL querystring?

I'm trying to submit a POST request with JSON data to an api endpoint. The endpoint requires a querystring passing the api credentials, but also requires the JSON data to be POSTed.
When I try to do this with PHP cURL as shown below, the querystring is apparently removed - thus the api is rejecting the request due to missing api key.
I can do this easily with Postman when testing access to the api endpoint.
How can I make the cURL request include both the querystring AND the JSON POST body?
Example code:
// $data is previously defined as an array of parameters and values.
$url = "https://api.endpoint.url?api_key=1234567890";
$ch = curl_init();
$json = json_encode($data);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($json)
]
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
You are doing almost right.
Sometimes you need to relax SSL verification.
Otherwise, update php ca bundle:
https://docs.bolt.cm/3.7/howto/curl-ca-certificates
Add the following:
$headers = array(
"Content-type: application/json;charset=UTF-8",
"Accept-Encoding: gzip,deflate",
"Content-length: ".strlen($json),
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_ENCODING, "identity, deflate, gzip");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
Sometimes you need to change encoding too:
$result = utf8_decode($result);
And check the returning data.

Zoho API V2 Update Record

I am trying to use the Zoho API Version 2 to do a simple record update in Leads. I am using PHP and CURL and my sample code for this call (to update a single field in the record) is as follows:-
$apiUrl = "https://www.zohoapis.com/crm/v2/Leads/" . {valid record id here};
$headers = array(
'Content-Type: application/json',
'Content-Length: ' . strlen($fields),
sprintf('Authorization: Zoho-oauthtoken %s', {valid auth token here})
);
$fields = json_encode([["data" => ["City" => "Egham"]]]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$result = curl_exec($ch);
curl_close($ch);
No matter how I format the JSON, I always get the following returned:
{"code":"INVALID_DATA","details": {"expected_data_type":"jsonobject"},"message":"body","status":"error"}
It is not a matter of invalid auth tokens etc because I have successfully used PHP and CURL with the Zoho API to read data and I decode the JSON returned successfully.
Please could somebody help with passing valid JSON data?
The above code constructs input JSON like this
[{"data":{"City":"Egham"}}]. This JSON is not valid as per the ZOHO CRM APIs(API help).
It should be like this {"data":[{"City":"Egham"}]}.
Change the code like this :
$apiUrl = "https://www.zohoapis.com/crm/v2/Leads/" . {valid record id here};
$fields = json_encode(array("data" => array(["City" => "Egham"])));
// *strlen must be called after defining the variable. So moved headers down to $fields*
$headers = array(
'Content-Type: application/json',
'Content-Length: ' . strlen($fields),
sprintf('Authorization: Zoho-oauthtoken %s', {valid auth token here})
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$result = curl_exec($ch);
curl_close($ch);
You must escape the data into JSON format:
import json
response = requests.post(url, data=json.dumps(data), headers=headers)

PHP POST to API with JSON Body and Auth

I am in the process of creating a super simple PHP page that sends JSON data to an remote API via POST. I am having issues with it and hoping someone here could help me out.
This is what I have so far
$url = "https://remoteHost.com/api/post";
$json = '{"message":"textHere", "user":"userABC"}';
$ch = curl_init();
$timeout = 0;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: Basic --ACB123-ABC123---ABC123---',
'Content-Type: application/json',
'Content-Length: ' . strlen($json),)
);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
When I execute this nothing happens. The page loads without errors but it looks like the curl isn't actually doing anything. Any Ideas?

when CURLOPT_HTTPHEADER need 'Content-Length'

I have this code in the client side of my application:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length:0 ' )
);
$body = curl_exec($ch);
while in the server files:
$ch = curl_init($this->modelAddress);
$data = array("params"=>array("resource" => "artist","operation" => $operation,"params"=>$params));
$data_string = json_encode($data);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
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))
);
They are made from 2 different people and I want to ask what is the most correct.
When the use of 'Content-Length:0' instead of 'Content-Length:'.strlen($data_string) is better.
It's only question of POST/GET method?
I've searched explanations of this in the web but I've found nothing
If you use http PUT with curl then you have to specify the Content-Length header. Otherwise it is automatically handled by the curl for both GET and POST.
For example if you are posting the following data with curl with CURLOPT_POSTFIELDS. Then curl will automatically add the length of the data with the header.
$data = "name=alex&email=none!";
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
For better understand, run your curl code using verbose mode and you'll see how its handling the requests and responses.
curl_setopt($ch, CURLOPT_VERBOSE, true);

Categories