Problem converting a JSON object to PHP array - php

Am working on a Laravel application which consumes a backend API still written in Laravel. Am passing an array of data from the frontend to the backend via curl, The data is being passed fine but on the backend/API when I try to decode it to PHP array and get an individual property in the array, I keep getting null. What could I be missing out?
PHP array am passing
$data = [
'phone' => '254712345669',
'name' => 'John Doe',
'email' => 'doejohn#email.com',
];
$token = session('access_token');
$letter = GeneralHelper::global_Curl($data , $token , 'api/v1/travel-letter');
Curl function in GeneralHelper to pass data to the backend in Json format
static function global_Curl($data, $token , $url){
$server = 'http://localhost/digital-apps-apis/public';
$headers = ["Accept:application/json",
"Content-Type:application/json",
"Authorization:Bearer ".$token
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ($server.'/'.$url));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
$response = json_decode(curl_exec($ch));
dd($response);
curl_close($ch);
return $response;
}
API side where am retrieving the data
public function getLetter(Request $request){
return $request->all();
}
Data on the browser Network tab after returning from API side
{#368
+"phone": "254712345669"
+"name": "John Doe"
+"email": "doejohn#email.com"
}
When I decode the data so that I can get each single property I get null
public function getLetter(Request $request){
return json_decode($request->all() , true);
}

if json_decode returns null, it means that the given data is not a valid json string. the fact that in the network response the string starts with a #368 suggests me that is an object dump rather than a string. Try to double check that.
Also, probably you know that and it's a leftover form the debug but you have a dd() inside your global_Curl function

Related

CURL Request to Laravel API Returns NULL Values

I'm attempting to send an array of objects as part of a JSON request with curl. The request must use json_encode in order to be sent by curl. However I am running into an issue on the Laravel API that is receiving it. Any attempt to get an object from the Request Laravel object returns null i.e.:
$request->order_number;
$request->items;
This is the case for normal fields and the array of objects I am also sending. The curl appears as:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/json'
));
What is the mistake I am making?
EDIT:
To provide more specific information, here is the json_encode var dumped (some omissions):
string(694) "{"order_number":"11111","items":"[{"id":"1005","name":"UpRight 011238-004 Washer, Split Lock","sku":"","quantity":1,"price":0.01}]"}"
The solution ended up being rather convoluted:
public function postOrderInformation(Request $data) {
$request = json_decode(json_encode(json_decode($data->getContent(), true)));
}
This created a useable object from which the data could be extracted from the laravel Requets object. If anyone has a more elegant/less ugly solution, please post it.

How can I handle data returned from an API endpoint (django application) in a php laravel application route

I have a Django API application using Django rest framework which works just fine. I have another PHP laravel application that is supposed to consume the API. When I post data to the API endpoint using curl, the data is stored and an object is returned.
I am supposed to grab this object and use the data. However, the object that is returned is printed on the page when I visit the route that executes the post request.
When I do dd($data) with the variable that is supposed to contain the returned data, I get a boolean (true when the data was posted successfully and false if something went wrong).
Route::get('test-create-client', function (){
try {
$data = ApiController::createClient('John D', '0711111111', '', 'Male', '1980'.'-'.date('m-d'));
} catch (Exception $exception) {
return $exception->getMessage();
}
dd($data); // I get a boolean from here
});
//creatClient from the ApiController
public static function createClient($name, $phone, $care_of, $gender, $date_of_birth)
{
$url = "client/clients/";
$client = '{
"name": "'.$name.'",
"telephone_number": "'.$phone.'",
"alternative_telephone_number": "'.$alt_phone.'",
"care_of": "'.$care_of.'",
"gender": "'.$gender.'",
"date_of_birth": "'.$date_of_birth.'",
}';
return ServicesApiController::RunCurlPostServices($url, $client);
}
//CurlRequest
public static function RunCurlPostServices($url, $json)
{
$ch = curl_init(env('SERVICES_API_URL').$url);
curl_setopt($ch, CURLOPT_POST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"authorization: token *******"));
return curl_exec($ch);
}
I need $data to have the data returned by the API endpoint and not a boolean value.
In order for curlpost to return the content returned by an API request, I had to set CURLOPT_RETURNTRANSFER to true. For some reason I had missed it out.
So updating my curl request to
public static function RunCurlPostServices($url, $json)
{
$ch = curl_init(env('SERVICES_API_URL').$url);
curl_setopt($ch, CURLOPT_POST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"authorization: token *******"));
return curl_exec($ch);
}
Fixed the issue.
This helped.
Thanks for the effort #Rezrazi
Laravel does not have a built in http client, for that you need to use a tool or a package.
I recommend guzzle and its documentation
You can use it this way in your GET method
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://myapplication.com/endpoint');
$data = $res->getBody();

Postman and cURL is returning different output

This is url I'm running in the postman :- http://213.252.244.214/create-signature.php. It has two parameters string and key. It will return input which you have entered and the output which is RJAGDhoz8yDJ7GwVLberI/NMYy2zMTTeR9YzXj7QhCM= but if I run it from the curl then it is returning D9UmS6r/qg0QI/0eIakifqrM3Nd1g6B3W7RCsiyO7sc=. The output is in JSON Format. Following is the cURL code:-
public function create_signature($input, $key) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'http://213.252.244.214/create-signature.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "string=$input&key=$key");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
$json = json_decode($output);
$signature = $json->output; echo $signature; echo '<br>';
curl_close($ch);
return $signature;
}
sample string is:- 2019-01-23 14:00:594lzUTYHw01dW5EmPan01M07hEiWUaEmdKl3kzpUUqak=Ha2wZwz46l7vSboxVNx3/DAUYsInjjKtAbDSnPsdDnA=igK7XzaTBrusPc3q5OEOQg==igK7XzaTBrusPc3q5OEOQg==1.0.110671523012111548248459fR9b/McBCzk=Deposit Fund698EURLuisTurinTurinVenis13212TF990303274103325689667lg#gmail.comLuisTurinTurinVenis13212TF990303274103325689667lg#gmail.comLuisTurinTurinVenis13212TF990303274103325689667lg#gmail.comclient_deposithttp://localhost/feature/CD-716/gateways/certus_finance/paymenthttp://localhost/feature/CD-716/gateways/certus_finance/paymenthttp://localhost/feature/CD-716/gateways/certus_finance/payment
sample key is :- 85e1d7a5e2d22e46
Can anyone tell me why is it different?? Any help will be appreciated.
Your $input and $key values are not being encoded. From the curl_setopt() manual page...
This parameter can either be passed as a urlencoded string ... or as an array with the field name as key and field data as value
Postman does this by default.
To save yourself having to manually encode strings, just use the array method
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'input' => $input,
'key' => $key
]);
Take note of this caveat though...
Note:
Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data, while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.
If required, to ensure application/x-www-form-urlencoded, you can build an encoded string using http_build_query(), eg
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'input' => $input,
'key' => $key
]));

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 struggling to decode JSON

I have script that calls at script via cURL. It looks like this,
Route::get('login-redirect', function() {
if (Input::has('error')) {
return Input::get('error_description');
}
if (Input::has('code')) {
$fields = array(
'grant_type' => 'password',
'username' => 'admin#local.com',
'password' => 'passwohrd',
'client_id' => 'testclient'
);
$fieldstring = http_build_query($fields, "\n");
$url = "http://apitest.local/api/v1/get-token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fieldstring);
$result = curl_exec($ch);
$json = json_decode($result);
curl_close($ch);
$fields = array('access_token' => '3c1e6b099f172fc01304403939edf8e56904ab61');
$fieldstring = http_build_query($fields, "\n");
$url = "http://apitest.local/api/v1/me";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fieldstring);
$result = curl_exec($ch);
curl_close($ch);
dd($result);
}
The json returned looks like this, if I do dd($json)
{"content":null,"error":true,"error_description":"Invalid username and password combination"}int(1)
I feel like after running it through json_decode I should be able to just output $json->error but no.
The JSON gets made in the following class, but I cannot see anything odd here either, I am doing incorrect, or do I misunderstand json_decode?
<?php
namespace Shaunpersad\ApiFoundation\Http;
use App;
use Response;
class ErrorResponse
{
public static function make($message = '', $status = 200, array $headers = array(), $options = 0)
{
$response = App::make(
'api_response_array',
array(
'content' => null,
'error' => true,
'error_description' => $message
)
);
return Response::json($response, $status, $headers, $options);
}
}
First of all, you do not have CURLOPT_RETURNTRANSFER - your curl_exec returns output buffer directly to the screen.
Second of all, it looks like you have var_dump somewhere and I cannot see where :)
Third of all - you didn't asked any direct question.
Edit
Okay i've read it few time and answer below. The dd() function is truly a var_dump wrapper but it is dumping var_dump data into json format afaics.
What you've got as an output is not from dd($json):
// this part has been output by curl_exec():
{"content":null,"error":true,"error_description":"Invalid username and password combination"}
// only this part comes from dd($json):
int(1)
Here's why:
// no CURLOPT_RETURNTRANSFER, so curl_exec() outputs result and returns true:
$result = curl_exec($ch);
// thus $result = true;
// so here $json = 1, since this is what json_decode(true) will return
$json = json_decode($result);
// then you did dd($json), so it just appended var_dump(1) to the output:
{"content":null,"error":true,"error_description":"Invalid username and password combination"}int(1)
Update
As stated in the other answers, you're not actually receiving the output because you haven't set CURLOPT_RETURNTRANSFER. So curl_exec() will echo out the response to the DOM and return true (1) as your curl request ran successfully.
You'll be able to run the below stuff by setting this in your curl request somewhere:
curl_setop(CURLOPT_RETURNTRANSFER, true);
dd() is a laravel function and this is what the documentation says:
Dump the given variable and end execution of the script.
I'd presume it is just a wrapper function for a prettier looking var_dump() (As I don't use laravel, I wouldn't know its exact output.).
What you want is to decode the $result that is returned from your cUrl. Something like this should suffice:
$data = json_decode($result);
echo $data->error_description;
The successfully decoded object looks like this:
stdClass Object
(
[content] =>
[error] => 1
[error_description] => Invalid username and password combination
)
Example
You can even test your boolean error value like this now:
if($data->error) {
//....true
} else {
//....false
}

Categories