Posting to API with curl not working - php

$headers = array();
$headers[] = 'Authorization: hmac ' .$websiteKey.':'.$hmac .':'.$nonce . ':'.$time;
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl,CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
var_dump($result);
curl_close($curl);
I have the code above, i want to post to an api. Somehow its not working. I tried using a var_dump on the result variable. The result is:
string(117) "{"Message":"The request entity's media type 'application/x-www-form-urlencoded' is not supported for this resource."}"
Any idea why its not posting to the api?
The value of the $post=
{"AmountDebit":10,"Currency":"EUR","Invoice":"testinvoice 123","Services":{"ServiceList":[{"Action":"Pay","Name":"ideal","Parameters":[{"Name":"issuer","Value":"ABNANL2A"}]}]}}
Headers:
$headers[] = 'Authorization: hmac ' .$websiteKey.':'.$hmac .':'.$nonce . ':'.$time;

If you don't specify a Content-Type header when making a POST call with Curl, it will add one in with the value application/x-www-form-urlencoded.
From the Everything Curl book:
POSTing with curl's -d option will make it include a default header that looks like Content-Type: application/x-www-form-urlencoded. That's what your typical browser will use for a plain POST.
Many receivers of POST data don't care about or check the Content-Type header.
If that header is not good enough for you, you should, of course, replace that and instead provide the correct one.
Judging by your request, I imagine you'll need to add the following to the top of your script:
$headers[] = 'Content-Type: application/json';
But depending on the exact API you're posting to, this might need to be different.

Have You installed curl before using it.
If it not install try google for Curl installation
and use my curl function for post request its 100% working-
public function curlPostJson() {
$headers = [];
$headers[] = 'Content-Type: application/json';
$headers[] = 'Content-Length: ' .strlen(json_encode($paramdata));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($paramdata));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
$server_output = curl_exec($ch);
curl_close($ch);
return json_decode($server_output);
}

Related

Php cURL with calling an API with GRAPHQL

I am trying to call an api called Wave I have used cURL before but never with GRAPHQL queries. I am wondering what is wrong with the below when using cURL. I get an error Bad Request Below is an exmple of my code.
This is what the API cURL is
curl -X POST "https://reef.waveapps.com/graphql/public" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "query": "query { user { id defaultEmail } }" }'
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://reef.waveapps.com/graphql/public');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{ "query": "query { user { id defaultEmail } }');
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer 1212121';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
var_dump($result);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
Any help would be helpful.
For those wanting to query a GraphQL service WITHOUT a third party library, I basically took Brian's code and tested against a GraphCMS service I had already written Node.js code for. So I knew the url, authorization token, and query all worked.
<?php
$endpoint = "https://api-euwest.graphcms.com/v1/[[your id number here]]/master";//this is provided by graphcms
$authToken = "[[your auth token]]";//this is provided by graphcms
$qry = '{"query":"query {products(where:{status:PUBLISHED}){title,img,description,costPrice,sellPrice,quantity,sku,categories {name},brand {name}}}"}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer '.$authToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
var_dump($result);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
?>
All worked fine.
The auth token is a big long character string provided by GraphCMS and only needs to be passed in the header. So no real tricky authentication process - as long as you have the token.
I can recommend using https://github.com/softonic/graphql-client, it has worked great for us.
A way easier way to go about doing this is by using an API platform. I often use Postman, the platform have the functionality to give you the PHP cURL code for a GraphQL request in the GraphQl tools part of the application.
You can create your own client passing whatever middleware you'd like:
$clientWithMiddleware = \MyGuzzleClientWithMiddlware::build();
$graphQLClient = new \Softonic\GraphQL\Client(
$clientWithMiddleware,
new \Softonic\GraphQL\ResponseBuilder()
);
For an example how to build a Guzzle client with middleware you can check this out:
https://github.com/softonic/guzzle-oauth2-middleware/blob/master/src/ClientBuilder.php
If there is no authentication
You can use file_get_contents instead of curl
$url = http://myapi/graphql?query={me{name}}
$html =file_get_contents($url);
echo $html;
use json in query paramter for graphql;
Bit late but I made this code
$endpoint = "https://gql.waveapps.com/graphql/public";
$authToken = ""; //Your Bearer code
$qry = '{"query": "query {user {id firstName lastName defaultEmail createdAt modifiedAt}}"}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Bearer '.$authToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
var_dump($result);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}

Twitter API token request returning gobbledygook

I'm trying to use Application Only Authentication, as described here:
https://developer.twitter.com/en/docs/basics/authentication/overview/application-only
I'm using the following PHP code to do so.
if(empty($_COOKIE['twitter_auth'])) {
require '../../social_audit_config/twitter_config.php';
$encoded_key = urlencode($api_key);
$encoded_secret = urlencode($api_secret);
$credentials = $encoded_key.":".$encoded_secret;
$encoded_credentials = base64_encode($credentials);
$request_headers = array(
'Host: api.twitter.com',
'User-Agent: BF Sharing Report',
'Authorization: Basic '.$encoded_credentials,
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8',
'Content-Length: 29',
'Accept-Encoding: gzip'
);
print_r($request_headers);
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/oauth2/token');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
$attempt_auth = curl_exec($ch);
print_r($attempt_auth);
}
It should return JSON with the token in it, but instead it returns gobbledygook, as seen in the image below:
I'm sure I'm missing some very simple step, where am I going wrong?
If I send the curl request without the headers, it returns an error in JSON format as expected, so is there something wrong with my headers?
You have few options here. Instead of setting header directly, use below
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
If you set header directly then you should use
print_r(gzdecode($attempt_auth));
See below thread as well
Decode gzipped web page retrieved via cURL in PHP
php - Get compressed contents using cURL

Using cURL to return API XML response

Forgive me if this is simple. My research has brought me to a halt at the moment. I am trying to use cURL to get the response of an API in XML.
This is the URL of the API: https://api.weather.gov/alerts/active/region/land
By default it returns in JSON. Which I know, I should just use the JSON response but, there is a reason I need it in XML as it will seamlessly integrate into my current code until I can rewrite it for JSON.
This is the documentation for the API. Under the API Reference tab is states I just need to change the request header to application/cap+xml. But I am not getting anything back. Just a blank white page.
https://alerts-v2.weather.gov/documentation
Here is my current code I am using to call the API but I get no response or anything. What am I missing?
<?php
$headers[] = 'Connection: Keep-Alive';
$headers[] = 'Content-Type: application/cap+xml;charset=utf-8';
$headers[] = 'Accept: application/cap+xml';
$userAgent = 'php';
$url = 'https://api.weather.gov/alerts/active/region/land';
$cURL = curl_init();
curl_setopt($cURL, CURLOPT_URL, $url);
curl_setopt($cURL, CURLOPT_HTTPHEADER, $headers);
curl_setopt($cURL, CURLOPT_USERAGENT, $userAgent);
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cURL, CURLOPT_HTTPGET, true);
$result = curl_exec($cURL);
curl_close($cURL);
?>
I've just tried your code and it works fine with atom:
$headers[] = 'Accept: application/atom+xml';
"application/cap+xml" is not available for the URLs, like you mentioned in a question though.
Per the doc https://alerts-v2.weather.gov/documentation the formats are following:
/alerts/active/region/{region} => JSON-LD (default), ATOM
/alerts/{alertId} => JSON-LD (default), CAP

Sending GET request to REST API with custom header

I am trying to send a GET request to a REST API with a custom header, and I've followed tutorials and looked on here, but nothing I tried has worked. Am I missing something from this code?
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://manager.gimbal.com/api/beacons/");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$headers = array(
'Content-type: application/json',
'authorization: Token token={token}',
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);
curl_close($curl);
print($result);
?>
I have the correct token, it worked when I used a REST client.

PHP HTTP CURL PUT request for LIFX Power On/Off

I'm trying to power all of my Lifx bulbs on/off using PHP.
The API documentation, http://developer.lifx.com/, says to use a PUT request:
curl -u "c87c73a896b554367fac61f71dd3656af8d93a525a4e87df5952c6078a89d192:" \
-X PUT \
-d "state=on" \
"https://api.lifx.com/v1beta1/lights/all/power"
Now using that curl command works in the command line. It prompts me for my password unless I add it after the colon in the "username".
The trouble is when I try to translate that command into PHP like so:
$authToken = 'c87c73a896b554367fac61f71dd3656af8d93a525a4e87df5952c6078a89d192:myFakePassword';
$ch = curl_init('https://api.lifx.com/v1beta1/lights/all/power');
$headers = array("selector=all&state=on",'Authorization: Bearer ' . $authToken);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
This goes through, but I get a 404 Not Found which the Lifx documentation says is probably a malformed selector.
Note: I was able to make a successful call with PHP to toggle the power with this POST:
$authToken = 'c87c73a896b554367fac61f71dd3656af8d93a525a4e87df5952c6078a89d192';
$ch = curl_init('https://api.lifx.com/v1beta1/lights/all/toggle');
$headers = array("selector=all",'Authorization: Bearer ' . $authToken);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
But I don't want to just toggle the lights, I want to be able to specify on or off. What could be wrong with my PUT request?
Thank you for any suggestions.
Solved this by setting some other curl options:
$ch = curl_init($link);
$headers = array('Authorization: Bearer ' . $authToken);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = "state=on";
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$link is https://api.lifx.com/v1beta1/lights/all/power
$authToken is my api key

Categories