Using curl to post request handle JSON data - php

I recently work with kraken.io API and I'm trying to integrate this API wuth my PHP CodeIgniter framework. So I followed the documentation but I got stuck when I used curl
This is my source code below ..
require_once(APPPATH.'libraries/kraken-php-master/Kraken.php');
$kraken = new Kraken("SOME_KEY", "SOME_SECRET");
$params = array(
"file" => base_url()."include/".$dataIn['logo'],
"wait" => true
);
$dataj='{"auth":{"api_key": "SOME_KEY", "api_secret": "SOME_SECRET"},"file":'.base_url()."include/".$dataIn['logo'].',wait":true}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.kraken.io/v1/upload");
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataj);
$response = curl_exec($ch);
curl_close($ch);
$data = $kraken->upload($params);
print_r($response);exit();
And I got this result
"{"success":false,"message":"Incoming request body does not contain a valid JSON object"}1"
So can anyone please help me,
And thanks in advance,

DONT POST YOUR API_KEY AND API_SECRET
The error message is quite clear, your json object is not valid. For instance this would be a valid JSON object for your request:
{
"auth": {
"api_key": "SOME",
"api_secret": "SECRET"
},
"file": "somefile.txt",
"wait": true
}
In your php code you are setting up a $params array but then you don't use it. Try this:
$dataj='{"auth":{"api_key": "SOME_KEY", "api_secret": "SOME_SECRET"},"file":"' . $params["file"]. '", "wait":true}';
You can validate your JSON HERE

You should use json_encode function to generate your JSON data
$dataj = json_encode([
"auth" => [
"api_key" => "API_KEY",
"api_secret" => "API_SECRET"
],
"file" => base_url() . "include/" . $dataIn['logo'],
"wait" => true
]);
EDIT:
Here is an example from https://kraken.io/docs/upload-url so you don't need to use curl
require_once("Kraken.php");
$kraken = new Kraken("your-api-key", "your-api-secret");
$params = array(
"file" => "/path/to/image/file.jpg",
"wait" => true
);
$data = $kraken->upload($params);
if ($data["success"]) {
echo "Success. Optimized image URL: " . $data["kraked_url"];
} else {
echo "Fail. Error message: " . $data["message"];
}

Related

Pass whole incoming data to curl - Laravel

I wanted to pass the whole incoming data (that is, $request) to the curl not wanted to post to a particular field in the endpoint as subjectId=>1 as am running this curl request for different endPoint everytime. The below curl request will work if CURLOPT_URL => $url . $subjectId, was given. As my input changes for every end point, i've to pass everything that comes in the input to the curl , i can't pass it as an arary $subjectId. Is there any way to do this?
Currently, dd($Response); returns null
Am giving a postman input like this:
{
"subjectId":"1"
}
Curl
public function getContentqApiPost(Request $request)
{
$token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ey";
$headers = [
"Accept: application/json",
"Authorization: Bearer " . $token
];
$url="http://127.0.0.1:9000/api/courses/course-per-subject";
$subjectId = "?subjectId=$request->subjectId";
$ch = curl_init();
$curlConfig = array(
// CURLOPT_URL => $url . $subjectId,
CURLOPT_URL => $url . $request,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt_array($ch, $curlConfig);
$result = trim(curl_exec($ch));
$Response = json_decode($result, true);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
echo $error_msg;
}
curl_close($ch);
return $Response;
}
If you would like to pass all params of $request to curl:
$queryParams = '';
$delimeter = '?';
foreach($request->all() as $k => $v){
$queryParams .= "$delimeter$k=$v";
$delimeter = '&';
}
Also You can only pass the params you want:
foreach($request->only(['subjectId']) as $k => $v){
// code here
}
Finally you have:
CURLOPT_URL => $url . $queryParams,
Answer
Assuming you want to pass the entire GET query string as-is:
$query_string = str_replace($request->url(), "", $request->fullUrl());
$url = "http://localhost:9000/api/courses/course-per-subject" . $query_string;
This works because $request->url() returns the URL without the query string parameters, while $request->fullUrl() returns the URL with all the query string parameters, so we can use str_replace with an empty replacement to remove the non-query part. Note that $query_string will already start with a ? so there is no need to add that yourself.
Other suggestions
Unless your Laravel API is a 1:1 copy of the backend API, I strongly suggest writing a class that interfaces with the backend API, then provide it to your Laravel controllers using dependency injection. E.g.
class CourseCatalogApi {
public function getSubjectsInCourse(String $course){
... // your curl code here
}
}
Finally, since you are already using Laravel, there is no need to write such low level code using curl to make HTTP requests. Consider using guzzlehttp, which is already a dependency of Laravel.

CURL with JSON from laravel to API

I am trying to implement an API call from my system, and the API has an example that looks like this:
curl -u "<brugernavn>:<password>" -XPOST http://distribution.virk.dk/cvr-permanent/_search -d'
{ "from" : 0, "size" : 1,
"query": {
"term": {
"cvrNummer": 10961211
}
}
}
'
Now i want to turn this in to php code. Im thinking it will look something like this:
public function requestApiV2($vat){
// Start cURL
$ch = curl_init();
// Determine protocol
$protocol = 'http';
$parameters = json(
{ "from" : 0, "size" : 1,
"query": {
"term": {
"cvrNummer": $vat
}
}
}
);
// Set cURL options
curl_setopt($ch, CURLOPT_URL, $protocol . '://distribution.virk.dk/cvr-permanent/_search' . http_build_query($parameters));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Parse result
$result = curl_exec($ch);
// Close connection when done
curl_close($ch);
// Parse from json to array
$data = json_decode($result, true);
}
I can't test this yet, as I still need to acquire username and password from the API, but I am also uncertain about how I send the username and password along with the request in the correct way. Is there a CURLOPT for this as well?
I am also uncertain about if my parameters are implemented the right way with the json like that.
thank you :)
use Guzzle library. Laravel has included the Guzzle library so you dont need to install it
With Guzzle, the below will do
use GuzzleHttp\Client;
public function requestApiV2($vat){
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://distribution.virk.dk/,
]);
$response = $client->post('cvr-permanent/_search', [
'auth' => ['username', 'password'],
'json' => [
'from' => 0,
'size' => 1,
'query' => [
'term' => [
'cvrNumber' => $vat
]
]
]
]);
$body = $response->getBody();
dd($body);
}

create folder with microsoft graph api

I'm try to create folder, using microsoft graph API. In microsoft graph explorer, all work fine, but my php code return an error:
$name = 'newFolder'; $access_token = '123..';
$link = 'https://graph.microsoft.com/v1.0/me/drive/root/children';
$data = array(
"name" => $name,
"folder" => array()
);
$curl=curl_init();
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_URL,$link);
curl_setopt($curl,CURLOPT_CUSTOMREQUEST,'POST');
curl_setopt($curl,CURLOPT_HEADER,false);
curl_setopt($curl,CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$access_token, 'Content-Type: application/json'));
curl_setopt($curl,CURLOPT_POSTFIELDS, $data);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,0);
$out = curl_exec($curl);
$codeCurl = curl_getinfo($curl,CURLINFO_HTTP_CODE);
curl_close($curl);
this is response of '$out': 400 BadRequest, Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format. I'm can't understand, what wrong? json data is correct, headers too..
The microsoft graph API documentation shows this example request for create folder:
POST /me/drive/root/children
Content-Type: application/json
{
"name": "New Folder",
"folder": { },
"#microsoft.graph.conflictBehavior": "rename"
}
To get this part of the request : "folder": { } you could either put "folder" => new stdClass() in your $data array or keep this "folder" => array() and use json_encode($data, JSON_FORCE_OBJECT). If you use JSON_FORCE_OBJECT, all arrays will be encoded as objects.
I had the same problem, but error in the response was a bit different: Property folder in payload has a value that does not match schema. I am using "folder" => new stdClass() and it works fine.
The right way is using "json_encode()" to put data in a right format. And correct format for the folder was $folderParameters = ["name" => $name, "folder" => ["childCount" => '0']]; (thank Create folder on OneDrive with API)
The right code is :
$link = 'https://graph.microsoft.com/v1.0/me/drive/root/children';
$data = [
"name" => $name,
"folder" => ["childCount" => '0']
];
$headers = [
'Authorization: Bearer '.$access_token,
'Content-Type: application/json'
];
$curl=curl_init();
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_URL,$link);
curl_setopt($curl,CURLOPT_CUSTOMREQUEST,'POST');
curl_setopt($curl,CURLOPT_HEADER,false);
curl_setopt($curl,CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,0);
$out = curl_exec($curl);
$codeCurl = curl_getinfo($curl,CURLINFO_HTTP_CODE);
curl_close($curl);

decision making based on json array

I am working on an payment gateway API to process refunds.
On successful operation, the API returns a json array like this
{
"currencyCode" : "GBP",
"amount" : 100,
"originalMerchantRefNum" : "MERCHANTREF12346",
"mode" : "live",
"confirmationNumber" : 1997160616609792,
"authType" : "refund",
"id" : "25TWPTLHRR81AIG1LF"
}
On error the array returned is
{
"error": {
"code": "400",
"message": "Amount exceeds refundable amount"
}
}
I need to decode the json output and then show it to the user. But since the structure of the json array is different in both cases, how do I go arnd parsing the json array, so as to give relevant readable data to the end user.
My code which, does all the talking and fetching data from the gateway processor is given below
<?php
include('lock.php');
$flag=0;
$oid=$_POST['oid'];
if(isset($_POST['amount']))
{
$amount=$_POST['amount'];
$amount = $amount*100;
$flag=1;
}
// generate random number
$merchantref=mt_rand(10,9999999999);
//API Url
$url = 'https://api.netbanx.com/hosted/v1/orders/'.$oid.'/refund';
//Initiate cURL.
$ch = curl_init($url);
//The JSON data.
if($flag==1)
{
$jsonData = array(
"amount" => $amount,
'merchantRefNum' => $merchantref
);
}
else
{
$jsonData = array(
'merchantRefNum' => $merchantref
);
}
//Encode the array into JSON.
$jsonDataEncoded = json_encode($jsonData);
//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);
//Attach our encoded JSON string to the POST fields.
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//Set the content type to application/json and HTTP Authorization code
$headers = array(
'Content-Type:application/json',
'Authorization: Basic '. base64_encode("..") //Base 64 encoding and appending Authorization: Basic
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Execute the request
$result = curl_exec($ch);
$jdata=$result;
//decode the json output and store it in a variable
$jfo = json_decode($jdata);
//Handle decision making based on json output
?>
Basically something as simple as:
$response = json_decode(..., true);
if (isset($response['error'])) {
echo 'Sorry, ', $response['error']['message'];
} else {
echo 'Yay!';
}
What exactly you need to check for depends on the possible values the API may return. Most APIs specify something along the lines of "status will be set to 'success' or 'error'", or maybe "if the error key is present, this indicates an error, otherwise a success".

Send parameters to a URL and get output from that page

I have 2 pages say abc.php and def.php. When abc.php sends 2 values [id and name] to def.php, it shows a message "Value received". Now how can I send those 2 values to def.php without using form in abc.php and get the "Value received" message from def.php? I can't use form because when user frequently visits the abc.php file, the script should automatically work and get the message "Value received" from def.php. Please see my example code:
abc.php:
<?php
$id="123";
$name="blahblah";
//need to send the value to def.php & get value from that page
// echo $value=Print the "Value received" msg from def.php;
?>
def.php:
<?php
$id=$_GET['id'];
$name=$_GET['name'];
if(!is_null($id)&&!is_null($name))
{ echo "Value received";}
else{echo "Not ok";}
?>
Is there any kind heart who can help me solve the issue?
First make up your mind : do you want GET or POST parameters.
Your script currently expects them to be GET parameters, so you can simply call it (provided that URL wrappers are enabled anyway) using :
$f = file_get_contents('http://your.domain/def.php?id=123&name=blahblah');
To use the curl examples posted here in other answers you'll have to alter your script to use $_POST instead of $_GET.
You can try without cURL (I havent tried though):
Copy pasted from : POSTing data without cURL extension
// Your POST data
$data = http_build_query(array(
'param1' => 'data1',
'param2' => 'data2'
));
// Create HTTP stream context
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $data
)
));
// Make POST request
$response = file_get_contents('http://example.com', false, $context);
Taken from the examples page of php.net:
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "example.com/abc.php");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
Edit: To send parameters
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( tch, CURLOPT_POSTFIELDS, array('var1=foo', 'var2=bar'));
use CURL or Zend_Http_Client.
<?php
$method = 'GET'; //change to 'POST' for post method
$url = 'http://localhost/browse/';
$data = array(
'manufacturer' => 'kraft',
'packaging_type' => 'bag'
);
if ($method == 'POST'){
//Make POST request
$data = http_build_query($data);
$context = stream_context_create(array(
'http' => array(
'method' => "$method",
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $data)
)
);
$response = file_get_contents($url, false, $context);
}
else {
// Make GET request
$data = http_build_query($data, '', '&');
$response = file_get_contents($url."?".$data, false);
}
echo $response;
?>
get inspired by trix's answer, I decided to extend that code to cater for both GET and POST method.

Categories