Reading the Guzzle response with some nested JSON objects - php

I have made a http request to my api using Guzzle library as follow :
$client = new Client();
$response = $client->request(
'GET',
config('some_url');
$serverResponse = json_decode($response->getBody(),true);
if ($serverResponse['result']) {
$data = $serverResponse['data'];
Now I got the response as
{
"result": true,
"data": {
"101": {
"id": 101,
"name": "ABCD",
"age" : 24
},
"102": {
"id": 102,
"name": "EFGH",
"age" : 24
},
"103": {
"id": 103,
"name": "IJKL",
"age" : 24
},
}
}
The problem is I need to read and push the object models 101,102,103 to a separate array. for this I try to get the objects as following options. but I could not able to get the results rather than errors.
$obj = $data[0];
It returns Undefined offset: 0 error

Because your data is being manually indexed, as opposed to something like:
{
"data": {
0: {
"id": 101,
...
},
1: {
"id": 102,
...
},
...
}
}
You will need to specify these indexes when fetching the data. E.g:
$data["101"]
To do this for dynamically set data you can use array_keys
$obj = $data[array_keys($data)[0]];
Using array_keys allows you to search $data by the numerical index of $data

If you simply want to re-index the array so that the keys are [0], [1], [2], etc. you can use the following:
$newArray = array_values($data);
You will then be able to access the first sub-array with $newArray[0], the second with $newArray[1], etc.

You can convert the response to object and then you can access the properties as following.
$obj = json_decode($response->getBody());
$one_zero_one = $obj->data->{101};

Related

I need to obtain the key string from JSON

I have this JSON in a request for an laravel API:
{
"questionary": {
"directLeader": {
"answer": "ALWAYS",
"comments": "asdf"
}
},
"id": 14
}
I need to obtain the string "directLeader" 'cause this key changes in the request and I used that as a reference for a query update.
To convert json to array:
$array = json_decode($json, true);
To get the first key inside associative array:
$firstKey = array_key_first($array['questionary']);
$firstKey will contain your dynamic key.
You need to json_decode() the json you have like so
$json = '{
"questionary": {
"directLeader": {
"answer": "ALWAYS",
"comments": "asdf"
}
},
"id": 14
}';
$encoded_json = json_decode($json, true);
dd($encoded_json['questionary']['directLeader']);
Note
the true in json_decode() will convert the object to array, without true it will an object

php foreach Iteration through json

Assume that I have below json response fetched from an API.
{
"owner": "Jane Doe",
"pets": [
{
"color": "white",
"type": "cat"
},
{
"color": "black",
"type": "dog"
}
]
}
From the below PHP code I have converted the json string into a json object. And displayed the pet types.
$jsonObject = json_decode($json);
foreach($jsonObject->pets as $pets){
echo 'Pet type:'.$pets->type.'</br>';
}
However in some cases the response json from the API is in below format
{
"owner": "John Doe",
"pets": {
"color": "white",
"type": "cat"
}
}
in this case above php foreach iteration fails with below message
*Notice: Trying to get property of non-object *
I'm looking for a easy way to do this because the actual json response which i'm handling has lot of these occurrences.
You need to check whether $jsonObject->pets is an array or object. If it's an object, replace it with an array containing that object, then the loop will work.
if (!is_array($jsonObject->pets)) {
$jsonObject->pets = array($jsonObject->pets);
}
You could also do it with a conditional in the foreach:
foreach (is_array($jsonObject->pets) ? $jsonObject->pets : [jsonObject->pets] as $pet) {
...
}
If you don't want to have to write all that every time, you could put it in a function:
function as_array($x) {
return is_array($x) ? $x : [x];
}
and then use:
foreach (as_array($jsonObject->pets) as $pet) {
...
}
I'd also complain to the API designer. It's ridiculous to return inconsistent data formats like this.

Decoding and looping through PHP JSON array

I have the following deocoded JSON array.
I need to access the "type" inside the context, as well as I need to loop through each of the values in the payload. How do I do that?
{
"RequestHeader":
{
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context" :
{
"type": "friends,circles"
}
"payload" [ {12345},{12345} ,{2345} ]
}
I tried the following, but it doesn't work
$decoded = json_decode($json_string);
for ($i=0;$i<payload.length;++$i)
{
$id=$decoded->payload[$i];
//do some operation with the id
}
First of all the JSON you provided is invalid. Supposedly the valid one should look like this
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
After you've fixed the problem with JSON provider it will be quite easy to access data
<?php
$json = <<<'JSON'
{
"RequestHeader": {
"mess": "am putting it on my wall....",
"created_time": "2010-08-24T09:01:25+0000"
},
"context": {
"type": "friends,circles"
},
"payload": [
12345,
12345,
2345
]
}
JSON;
$data = json_decode($json, true);
$type = $data['context']['type'];
var_dump($type);
foreach($data['payload'] as $id) {
var_dump($id);
}
Remember to make sure you check that the data actually exists before accessing it, e.g. isset($data['context']['type']) unless you are absolutely sure in it's integrity.
When you use json_decode method, the output will be nested arrays
So for example to access context type you need to do the following
echo $decoded["context"]["type"];
And to loop on payload you need to do the following
for ($i=0;$i<$decoded["payload"].length;++$i)
{
$id=$decoded["payload"][$i];
//do some operation with the id
}

array of objects selecting object based on attribute value

I am working with the Mailchimp API at the moment, I have a list of campaigns that have been run, or are due to be run, and I wanting to get the link for the most recently run campaign. How would I go about comparing the attribute "send_time" to find the most recent and it's attributed parent object?
The campaigns array looks like this,
{
"campaigns": [
{
"id": 1,
"type": "regular",
"status": "save",
"send_time": ""
},
{
"id": 2,
"type": "regular",
"status": "sent",
"send_time": "2015-11-11T14:42:58+00:00"
},
{
"id": 3,
"type": "regular",
"status": "sent",
"send_time": "2016-01-01T14:42:58+00:00"
},
{
"id": 4,
"type": "regular",
"status": "sent",
"send_time": "2016-06-12T14:42:58+00:00"
}
]
}
So in that above array, the final object has the most recent send_time, how would I assess this, and then grab that object? I have a semi solution, but it seems long winded.
<?php
//Build an array of send_times
$dates = [];
foreach($result['campaigns'] as $campaign) {
$dates[$campaign['id']] = $campaign['send_time'];
}
//Get the most recent date
$mostRecent = 0;
foreach($dates as $k => $v) {
$curDate = strtotime($v);
if($curDate > $mostRecent) {
$mostRecent = $curDate
$currentId = $k;
}
}
//Get the object
foreach($results['campaigns'] as $campaign) {
if($campaign['id'] == $currentId) {
$c = $campaign;
}
}
?>
Use array_multisort() like below (single line code):-
<?php
$data = '{
"campaigns": [
{
"id": 1,
"type": "regular",
"status": "save",
"send_time": ""
},
{
"id": 2,
"type": "regular",
"status": "sent",
"send_time": "2015-11-11T14:42:58+00:00"
},
{
"id": 3,
"type": "regular",
"status": "sent",
"send_time": "2016-01-01T14:42:58+00:00"
},
{
"id": 4,
"type": "regular",
"status": "sent",
"send_time": "2016-06-12T14:42:58+00:00"
}
]
}';
$array = json_decode($data,true)['campaigns']; // decode json string to array
array_multisort($array,SORT_DESC, SORT_STRING); // use of array_multisort
echo "<pre/>";print_r($array); // this will returns you indexed array like 0,1,2... you can again convert it to campaigns array like $final_array['campaigns'] = $array;
?>
Output:- https://eval.in/598349
Note:-
1.If your given data is in array already then no need to use json_decode(), directly use array_multisort() on it
https://eval.in/598355
For more reference:-
http://sg2.php.net/manual/en/function.array-multisort.php
<?php
$dates = [];
$recent_campaign = null;
$recent_time = 0;
foreach($result['campaigns'] as $campaign) {
$curDate = strtotime($campaign['send_time']);
if($curDate > $recent_time) {
$recent_time = $curDate
$recent_campaign = $campaign;
}
}
//$recent_campaign is the most recent campaign
?>
You can try this approach. Else you can use usort by send_time (direct solution).
I have not executed this code!
You can sort your objects by that property (I'd suggest usort, so that you can define your own sorting) and then get the first item in that array.
usort($result, function ($campaign1, $campaign2) {
if ($campaign1['send_time'] == $campaign2['send_time']) {
return 0;
}
return (strtotime($campaign1['send_time']) > strtotime($campaign2['send_time'])) ? -1 : 1;
});
$mostRecentCampaign = $campaign[0];
Note: I haven't run this, so you might have to tweak the return on the compare function if it's sorting in the wrong order.
If you just want to grab the max element and want to use fewer lines of code, try this:
Grab the max time by mapping the "send time" column to an epoch time and getting the max value
Filter your array by the entries that correspond to that max time
Profit
Example:
$dataArray = /* your array */
$maxTime = max(array_map('strtotime',array_column($dataArray["campaigns"], 'send_time')));
$maxEntry = array_filter($dataArray["campaigns"], function ($arr) use ($maxTime) { return strtotime($arr["send_time"])==$maxTime; });
print_r($maxEntry);
Would print:
Array
(
[3] => Array
(
[id] => 4
[type] => regular
[status] => sent
[send_time] => 2016-06-12T14:42:58+00:00
)
)
Note The advantage of this is that it doesn't need sorting. The disadvantage is that sorting and then getting the last element would be faster. However with sorting you lose the original array order which is sometimes needed.

add data to json (php)

can someone please help me to add data to following json.
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
}
],
"id": 102
}';
data to be added
$data1='{
"code": "abc3"
}';
Desired result
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
},
{
"code": "abc3"
}
],
"id": 10
}';
I can append data to $temp, but can someone please help to add data to specific position with php. Thank you in advance. (I've tried json_decode($temp, true) and then finding the location where data1 is to be added but failed).
You can convert your data to a normal PHP array:
$array = json_decode($temp, true);
then just add or change anything you want:
$array["data"][] = array(["code"] => "abc3");
and re-encode to json:
$temp = json_encode($array);// encode to json
http://php.net/manual/en/function.json-decode.php
first, you need to convert the JSON into PHP array like this:
$array = json_decode($temp, true);
Then, it's as simple as:
$array['data']['code'] = 'abc3';
If the string that you want to add is still a JSON, you have to convert that one in an array as well so:
$arr_to_add = json_decode($data1, true);
$array['data'][] = $arr_to_add;
In the end, of course, encode again like this:
$final_json = json_encode($array);
Hope this helps! :D
First you need to decode the json with json_decode. This returns a PHP variable.
Add desired values.
Use json_encode to get the json with new values. Returns a string containing the JSON.
you can try this:
<?php
$temp='{
"custId": 123,
"data": [
{
"code": "abc1"
},
{
"code": "abc2"
}
],
"id": 102
}';
$data1='{
"code": "abc3"
}';
$jarr=json_decode($temp,true);
$appArr=json_decode($data1,true);
$desire=array_merge($jarr,$appArr);
//print_r($desire);
echo json_encode($desire);

Categories