php variables inside json results in invalid json - php

I have the following json created dynamically using php variables and it gives me:
{"message":"invalid json"}
Code:
$json = '{
"sex": "'.$gender.'",
"age": '.$age.',
"evidence": [
{"id": "'.$symptom_id1.'", "choice_id": "present", "initial": true},
{"id": "'.$symptom_id2.'", "choice_id": "present", "initial": true},
{"id": "p_7", "choice_id": "'.$test1.'"},
{"id": "p_8", "choice_id": "'.$test2.'"},
{"id": "p_9", "choice_id": "'.$test3.'"},
{"id": "p_10", "choice_id": "'.$test4.'"},
{"id": "p_28", "choice_id": "'.$test5.'"},
{"id": "'.$location.'", "choice_id": "present"}
],
"extras": {
"disable_groups": true
}
}';
$ch = curl_init('https://api.infermedica.com/v2/diagnosis');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
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),
'app_id: '. APP_ID,
'app_key: '. APP_KEY,
'Interview-Id: '.$interview_id,
'User-Id: '. $hasheduser_id
]);
$result = curl_exec($ch);
echo '<pre>';
print_r( $result );
echo '</pre>';
Hard coding the values in place of variables works fine. Being a newbie, I am unable to understand the reason why it is not well formed.
Help requested.

You should never try and create valid JSON on your own, it will only lead to security issues and bugs, instead use a data structure and pass it to json_encode.
Example data structure for your use:
$to_json = [
'sex' => $gender,
'age' => $age,
'evidence' => [
['id' => $symptom_id1, 'choice_id' => 'present', 'initial' => true],
['id' => $symptom_id2, 'choice_id' => 'present', 'initial' => true],
['id' => 'p_7', 'choice_id' => $test_1],
['id' => 'p_8', 'choice_id' => $test_2],
['id' => 'p_9', 'choice_id' => $test_3],
['id' => 'p_10', 'choice_id' => $test_4],
['id' => 'p_28', 'choice_id' => $test_5],
['id' => $location, 'choice_id' => 'present'],
],
'extras' => [
'disabled_groups' => true
],
];
Then encode it:
$json = json_encode($jo_json);
Hope this helps.

Your JSON is invalid due to a typo on the 2nd line of your variable.
"age": '.$age.',
should be
"age": "'.$age.'",
Or what would be better
"age": "$age",
But the best way to accomplish what you are attempting to do would be to create a PHP array, and pass this to json_encode.
$array = ['hello, i am a key'=>'i am some data'];
var_dump(json_encode($array));

Related

Convert cURL to Guzzle Post sending json data

I have this cURL command that I need to convert to PHP using Guzzle 7. I've have been researching this for a few (well, more than a few) days and getting nowhere fast. The cURL command uses the Simpli.fi api to create an organization under the parent org.
curl -i -X POST -H "X-App-Key: xxxx-xx-xx-xx-xxxxxx" -H "X-User-Key: xxxx-xx-xx-xx-xxxxxx" \
-H "Content-Type: application/json" \
-d '{
"organization": {
"name": "My New Organization",
"parent_id": "5786",
"custom_id": "<Put your organization identifier here or omit this optional field>"
}
}' \
"https://app.simpli.fi/api/organizations"
I was able to convert it using this website but it doesn't use Guzzle: https://onlinedevtools.in/curl
Here's what it gave me:
include('vendor/rmccue/requests/library/Requests.php');
Requests::register_autoloader();
$headers = array(
'X-App-Key' => 'xxxx-xx-xx-xx-xxxxxx',
'X-User-Key' => 'xxxx-xx-xx-xx-xxxxxx',
'Content-Type' => 'application/json'
);
$data = '{\n "organization": {\n "name": "My New Organization",\n "parent_id": "5786",\n "custom_id": "<Put your organization identifier here or omit this optional field>"\n }\n }';
$response = Requests::post('https://app.simpli.fi/api/organizations', $headers, $data);
Here's what I've tried so far aside from the converted code above:
public static function createOrganization()
{
self::init();
$client = new Client(['debug' => true]);
$request = $client->request('POST',
self::$baseUrl.'/organizations', [
'multipart' => [
[
'name' => 'data',
'contents' => "{'organization':{'name':'Pete's Pet Pagoda','parent_id':'1052385'}}",
],
],
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
]
]);
dd($response = $request->getStatusCode());
}
I'm getting quite a few different errors however this is the latest:
curl_setopt_array(): cannot represent a stream of type Output as a STDIO FILE*
Can anyone tell me what I'm doing wrong? Is there something missing?
UPDATE: After further research into this issue and chatting with a developer on the Laracast Slack channel, I've come to learn that this is a bug with the ['debug' => true] option when running on a Windows system and is described on this GITHUB page: https://github.com/guzzle/guzzle/issues/1413
I'm running on a Windows 10 Pro system. I corrected it on my end by changing the debug option to use fopen() like this:
'debug' => fopen('php://stderr', 'w'),
I use PHPStorm. It suggested using the 'wb' to make it binary safe. After changing it, the post requests worked fine.
You need to use body, not multipart. You can also use json.
$request = $client->request('POST',
self::$baseUrl.'/organizations', [
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'body' => [
'{"organization":
[
{
"name":"Pete`s Pet Pagoda",
"parent_id":"1052385"
}
]
}',
],
]);
method 2
You can pass array to the json request option and it will convert it to json when sending the guzzle request. No need to use header as application/json as it applies internally.
$client->request('POST',
self::$baseUrl.'/organizations', [
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'json' => [
"organization" => [
[
"name" => "Pete`s Pet Pagoda"
"parent_id" => "1052385"
]
]
],
]);
I hope this will help you. For further debugging use Middleware::tap(find more help here middleware+json+request)
try{
$client = new Client();
$response = $client->request('POST', self::$baseUrl.'/organizations',
[
'headers' => [
'x-app-key' => self::$appKey,
'x-user-key' => self::$userKey,
'Content-Type' => 'application/json',
],
'json' => [
'organization' =>
[
"name" => "some_name_value",
"parent_id" => "id_here",
"custom_id" => "custom id here"
]
]
]);
$_response = json_decode($response->getBody()->getContents(), true);
}
catch(BadResponseException $e){
$response = $e->getResponse();
$errorArray = json_decode($response->getBody()->getContents(), true);
//echo "<pre>";
//print_r($errorArray);
//return some message from errorarray;
}

How to submit data using Guzzle?

I use Guzzle for calling an API (Fitnet). Everything is ok with GET request, but i've a problem with a POST request. Looks like no data is being sent to the API
My code is :
$contract = array("companyId" => 1,
"companyName"=> "",
"contractCreator" => "",
"contractCurrency"=> "",
"deliveryAmount"=> 12346,
"title"=> "blabla7",
"orderNumber"=> "numéro de commande",
"upperLimit"=> "",
"beginDate"=> "10/10/2019",
"billingDate"=> "10/10/2021",
"endDate"=> "10/10/2021",
"businessUnit"=> 0,
"businessUnitName"=> "",
"customerId"=> 48,
"billingMode"=> 2,
"billingPlanning"=> 0,
"billingPlanningName"=> "",
"profitCenter"=> "",
"status"=> 1,
"statusName"=> "",
"description"=> "",
"billableExpenses"=> true,
"contractCategoryDesignation"=> "",
"contractCategoryId"=> 2);
$res = $client->post('https://myurl.fitnetmanager.com/FitnetManager/rest/contracts/create', [
'headers' => ['Content-type' => 'application/json'],
'auth' => ['myemail', 'mypassword'],
'json' => [ 'Contract' => json_encode($contract) ]
]);
Can you help me ?
Thanks in advance,
F.
It works with :
$res = $client->post('https://myurl.fitnetmanager.com/FitnetManager/rest/contracts/create', [
'auth' => ['myemail', 'mypassword'],
'json' => $contract
]);
Thank you to #formvega :-)
Guzzle will encode the data into JSON for you, you should not encode it beforehand.
$res = $client->post('https://myurl.fitnetmanager.com/FitnetManager/rest/contracts/create', [
'auth' => ['myemail', 'mypassword'],
'json' => $contract
]);
You also don't need to specify the content-type header.

How to create this JSON in PHP?

Sorry for the bad title, but I don't know how to create following JSON in PHP:
{
"id":"1",
"method":"getData",
"params":{
"options":{
"element":{
"id":"1a_ext",
"type":1,
"keyType":"externalkey"
},
"moreInfo":true,
"userFields":[
"id",
"name",
"longname",
"externalkey"
]
}
},
"jsonrpc":"2.0"
}
I don't know to do the part after "params" (how do I "put" options "into" params) - for the other parts I know what I have to do:
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
$json = json_encode($json, true);
return self::request($json);
}
I would really appreciate your help, thanks!
You directly can assign to the params keys like
$json['params']['options'] = $your_options;
Full version of your code as an example
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
# add something to param index
$json['params']['options'] = $your_options;
$json = json_encode($json, true);
return self::request($json);
}
You can create the this in array format in PHP and then JSON encode:
$arr = [
'id' => 1,
'method' => 'getData',
'params' => [
'options' => [
'element' => [
'id' => '1a_ext',
'type' => 1,
'keyType' => 'externalKey'
],
'moreInfo' => true,
'userFields' => [
'id',
'name',
'longname',
'externalKey'
]
]
],
'jsonrpc' => '2.0'
];
$json = json_encode($arr);
Instead of spoonfeeding, i would like to help related, Whenever if you find difficulties to create an array representation of a JSON then you should use var_export(array, true) the second parameter must be true to return the variable representation instead of outputting it
<?php
$json_str = '{
"id": "1",
"method": "getData",
"params": {
"options": {
"element": {"id": "1a_ext", "type": 1, "keyType": "externalkey"},
"moreInfo": true,
"userFields": ["id", "name", "longname", "externalkey"]
}
},
"jsonrpc": "2.0"
}';
$json_arr = var_export(json_decode($json_str, true), true);
print_r($json_arr);
check the output here https://paiza.io/projects/eUZZDsTsSFSM4m9WMl05Ow
$json_arr is an array representation for your JSON, now you can dynamic the array values

Post Nested parameters using Curl in PHP

This is the Request body that I need to send- (Curl POST request in PHP)
$data = {
"paramOne" : "f733787d-5649",
"paramTwo": {
"format": "123XD"
},
"paramThree": [
{"type":"cn", "value":"Test User Manish 1"},
{"type":"c", "value":"US"}
]
};
I'm trying to use it at this line of my Curl Request in PHP-
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
The nested params are messing up the format in which I'm trying to send.
I already tried using http_build_query but then paramThree is causing problems.
I'm looking for the changes that I need to make to the format of $data before I use http_build_query on it.
It's JSON. You can either post it as a string (enclosed in quotes) or make an array first, convert it to JSON and then post it. Like this:
$array = [
'paramOne' => 'f733787d-5649',
'paramTwo' => [
'format' => '123XD'
],
'paramThree' => [[
'type' => 'cn',
'value' => 'Test User Manish 1'
],
[
'type' => 'c',
'value' => 'US'
]]
];
$data = json_encode($array);
In both cases use
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

Trying to take data out of this confusing StdClass [duplicate]

This question already has an answer here:
How to extract and access data from JSON with PHP?
(1 answer)
Closed 3 years ago.
I tried to connect Coinmarketcap's API using PHP curl to take out the live bitcoin price out of it as a practice. The point is that the output it gives is way too confusing that I have got no idea about how should I take the "price" out of it. There were some similar questions around but unfortunately, the responses didn't help me. So I was wondering how is it possible to take the price of bitcoin out of the return given by API? It seems like I'm misunderstanding arrays and objects since I'm still a newbie.
This is what "die and dump" returns:
#data: array:1 [▼
"response" => """
{
"status": {
"timestamp": "2019-04-15T14:03:35.573Z",
"error_code": 0,
"error_message": null,
"elapsed": 5,
"credit_count": 1
},
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"circulating_supply": 17646787,
"total_supply": 17646787,
"max_supply": 21000000,
"date_added": "2013-04-28T00:00:00.000Z",
"num_market_pairs": 7253,
"tags": [
"mineable"
],
"platform": null,
"cmc_rank": 1,
"last_updated": "2019-04-15T14:02:29.000Z",
"quote": {
"USD": {
"price": 5166.87433557,
"volume_24h": 11238888046.6075,
"percent_change_1h": 0.0140845,
"percent_change_24h": 1.39641,
"percent_change_7d": -0.981349,
"market_cap": 91178730855.57031,
"last_updated": "2019-04-15T14:02:29.000Z"
}
}
}
]
}
"""
]
Here is the code which requests from API:
function apiGet($url)
{
$parameters = [
'start' => '1',
'limit' => '3',
];
$query = http_build_query($parameters);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "$url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_TIMEOUT => 30000,
CURLOPT_POST => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept-Encoding: deflate, gzip',
'X-CMC_PRO_API_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
),
)
);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
print_r(json_decode($response));
}
return view('price', compact('response'));
}
$parameters = [
'start' => '1',
'limit' => '1',
];
$query = http_build_query($parameters);
$btc = new \App\Http\Controllers\CoinsController();
$result = $btc->apiGet('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest'."?".$query);
dd($result);
That's a nested key value array that contains a json string. You can get the price like this:
$price = json_decode($result['response'])->data[0]->quote->USD->price;
Also for your knowledge. You can use the Arr::get() helper provided by Laravel. See docs:
use \Illuminate\Support\Arr;
...
$data = json_decode($result['response'], true);
$price = Arr::get($data, 'data.0.quote.USD.price');

Categories