How to get a value from nested json in php - php

I am a beginner to JSON and i'm trying to get values from a json string. For example i want to read the first "t":1443502800 and assing it to a variable $beginTime and the second "t":1443790800 assigned to a variable $endTime
{
"op":"&",
"c":[
{
"type":"date",
"d":">=",
"t":1443502800
},
{
"type":"date",
"d":"<",
"t":1443790800
}
],
"showc":[true,true]
}
I would really appreciate any help :)
Edit code
foreach($rs2 as $record2)
{
if( $record2->availability == '{"op":"&","c":[],"showc":[]}'){
//skip, because the restriction date was not set for this attendance
}
else{
//get the restriction date by making use of json
$json_data = json_decode($record2->availability, true);
echo $json_data['c'];
}
}

You were almost there. The full call should be to
$beginTime = $json_data['c'][0]['t'];
since $json_data['c'][0] is the array:
array (
"type" => "date",
"d" => ">=",
"t" => 1443502800
),
The $endtime can be obtained in a similar manner:
$endTime = $json_data['c'][1]['t'];

The problem is you can't echo an array. You're trying to echo out $json_data['c'], which is an array. Either return it or echo out what you need. For instance to echo out the start time use echo $json_data['c'][0]['t']
ORIGINAL ANSWER
You should use json_decode without true in the second variable. Then you have objects (started with braces {) and arrays (started with square brackets [). You can then get the start and end times us
<?php
$string = '{
"op":"&",
"c":[
{
"type":"date",
"d":">=",
"t":1443502800
},
{
"type":"date",
"d":"<",
"t":1443790800
}
],
"showc":[true,true]
}';
$json = json_decode($string);
echo "Start time: ".$json->c[0]->t;
echo "End time: ".$json->c[1]->t;
Here's an eval.in of it working - https://eval.in/441599

Related

How can I access Json information in php using array indexing

I want to get all prices and add them. I was planning on using this to loop through the JSON but that would be another question. Am I approaching this the wrong way? Is there a better way to get the SUM of all prices?
I have found this answer which makes the same question but it does not work (duplicate: PHP: How to access array element values using array-index). Here is my JSON string.
{
"data": {
"230723": {
"2019-11-15": {
"price": 52,
"min_length_of_stay": 2,
"available": 1
},
"2019-11-16": {
"price": 90,
"min_length_of_stay": 2,
"available": 0
},
"2019-11-17": {
"price": 44,
"min_length_of_stay": 2,
"available": 0
},
"2019-11-18": {
"price": 44,
"min_length_of_stay": 2,
"available": 0
}
}
}
}
And here is my code:
$resultJson = file_get_contents('http://....');
$priceRange = json_decode($resultJson, true);
echo $priceRange['data']['230723']['2019-11-15']['price']; // working
//$priceRange = array_values($priceRange);
echo $priceRange[0][0][0][0]; // not working
The first echo works and return 52. The second echo does not work with or without the commented line (which was the answer to the duplicate question).
What am I missing?
Instead of changing the array from associative to numeric just loop through already existing array
Like this
$sum = 0;
$resultJson = file_get_contents('http://....');
$priceRanges = json_decode($resultJson, true);
foreach ($priceRanges['data'] as $id => $priceRange) {
if (!is_array($priceRange)) {
continue;
}
foreach ($priceRange as $date => $priceInfo) {
$sum += (isset($priceInfo['price']) ? intval($priceInfo['price']) : 0);
}
}
Well you know I hope that the data is in data and if you don't know the next key then reset helps. Then just get all price keys (hopefully you know this as well) and sum them:
$result = array_sum(array_column(reset($array['data']), 'price'));
Another way is using array_values on the first two levels:
$result = array_sum(array_column(array_values(array_values($array)[0])[0], 'price'));
To get each price the way you were trying to do you would need:
$result = array_values(array_values(array_values(array_values($array)[0])[0])[0])[0];
The code I wrote using Krzysztof Janiszewski answer, and works.
$sum = 0;
$priceRange = json_decode($resultJson, true);
foreach($priceRange as $item) {
foreach($item as $item2){
foreach($item2 as $item3){
$sum += $item3['price'];
}
}
}
echo $sum;

How can I trim data from a value inside array?

This is my data:
$d = $request->request->get('data');
The output:
[{"name":"form[id]","value":"10"},{"name":"form[name]","value":"Telefon2"},{"name":"form[uuid]","value":"bb80878ad4"},{"name":"form[productgroup]","value":"6"},{"name":"form[category]","value":"1"},{"name":"form[documents]","value":"7"}
I want to create a new array, that is removing extracting the variable inside the brackets.
function trim($d) {
preg_match('#\[(.*?)\]#', $d, $match);
return $match[1];
}
$dData = array_combine(array_column(trim($d), 'name'), array_column($d, 'value'));
$json = json_encode($dData);
But the error is
Warning: preg_match() expects parameter 2 to be string, array given
You're going to need to do a few things before you begin.
Firstly, rename the trim function to something like extract_name because PHP already has a built in trim function that removes whitespace from a string - or any character present in the character mask.
Secondly, you are going to need to iterate over each of the elements in the name column. You will notice the error you are getting from preg_match is because you are passing all values in one go.
Thirdly, I am assuming that the value of $d is an array of PHP objects. This is done, and assumed, in my solution using $d = json_decode($d);.
Using array_map instead of a foreach means we can have a nice one liner:
function extract_name($d) {
preg_match('#\[(.*?)\]#', $d, $match);
return $match[1];
}
$dData = array_combine(array_map('extract_name', array_column($d, 'name')), array_column($d, 'value'));
The output being:
array:6 [
"id" => "10"
"name" => "Telefon2"
"uuid" => "bb80878ad4"
"productgroup" => "6"
"category" => "1"
"documents" => "7"
]
Live demo
I believe you need smth like this
$d = ['{"name":"form[id]","value":"10"}', '{"name":"form[name]","value":"Telefon2"}', '{"name":"form[uuid]","value":"bb80878ad4"}', '{"name":"form[productgroup]","value":"6"}'];
function combine(array $d): array
{
$res = [];
foreach ($d as $item) {
$value = json_decode($item, true);
preg_match('#\[(.*?)\]#', $value['name'], $match);;
$columnName = $match[1];
$res[$columnName] = $value['value'];
}
return $res;
}
$dData = combine($d);
$json = json_encode($dData);
echo $json;```

Store record inside parent array

I have column date_added which has this format date 2017-02-09 08:45:48. I want to store all records of same month inside that specific month, like Feb month records should be inside Feb array. I'm trying following code.
$Res = array();
$query = $this->pdoConnection->prepare("select id,date from `record` ");
$query->execute();
header("Content-type: application/json; charset=utf-8");
$month = array(1,2,3,4,5,6,7,8,9,10,11,12);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$Data = $row;
$array_date = date("m", strtotime($row['date']));
$alpha_month = date("M", strtotime($row['date']));
if(in_array($array_date,$month)){
$Res[] = array($alpha_month=>array($Data));
}
}
$output = array(
'response' => $Res
);
echo json_encode($output,JSON_PRETTY_PRINT);
Result
{
"response": [
{
"Jan": [
{
"id": "1",
"date_added": "2017-01-03 08:43:09"
}
]
},
{
"Feb": [
{
"id": "4",
"date_added": "2017-02-04 10:53:44"
}
]
},
{
"Feb": [
{
"id": "2",
"date_added": "2017-02-12 08:59:15"
}
]
}
]
}
As you can see my code is return separate array of Feb, but i wanted to store both of inside Feb array. I have tried different logic but still facing same issue.
A little bit more detailed to my short comment above:
Instead $Res[] = array($alpha_month=>array($Data)); you could do $Res[$alpha_month][] = $Data;
Currently you're fetching all result tuples in this while loop which is accurate and okay. But if you want to "group" some results in an array, one way to go with is:
$Res[$alpha_month][] = $Data;
With this code you're "pushing" the result ($Data) in your $Res array. The important part is the first array layer $Res[$alpha_month] which relates to the new structure:
array('JAN', 'FEB', ...);
The second [] declares for the first layer, in this case it's your month group, another array. You may will get PHP WARNINGS by pushing your result for every month in the first time, because $Res[$alpha_month][] leads to a two-level declaration inside your array.
In the first declaration, as mentioned earlier, you're pushing all groups / months into the array! But in the same time, php expects the first iterative, to be an array as well: ($Res[$alpha_month][])
So the clean solution would be the following:
if(!isset($Res[$alpha_month])){
$Res[$alpha_month] = array(); // You can also use []; instead array();
}
$Res[$alpha_month][] = $Data;
With that snippet, you're first checking the $Res[$alpha_month] for existence - which also declares an array, if the current layer is not available.
You can try
$Res[$alpha_month][] = $data;
That will just add an entry to your array for that month, you also don't need the if(in_array($array_date,$month)) anymore

PHP changing array format

I'm trying to change an array format from this
{"updated":"2016-01-28 02:00:02","rate":"0.1898"}
to this
[2016-01-28 02:00 , 0.1898]
I'm getting the first array format from a MySQL query and need to convert to the second format to use in a line chart.
$newVal = array();
foreach ($dbresult as $key => $value) {
$newVal[] = json_encode(array_values($value));
}
echo implode(",", $newVal);
With this new code block i get this format
["2016-01-28 02:00" , "0.1898"]
But still need to get rid of the double quotes, any ideas?
$json = '[{"updated":"2016-01-28 02:00:02","rate":"0.1898"}]';
echo json_encode(array_map(function ($data) {
return [$data->updated, $data->rate];
}, json_decode($json)));
In other words:
JSON-decode it
loop through it
create a new array with updated in the first index and rate in the second
JSON-encode it again
Step 3 is necessary since JSON objects don't guarantee any particular order, so relying on the decoded order of the keys is not reliable; and it also guarantees you get the data you want even if you add more keys to your objects.
Try this code
$string = ' {"updated":"2016-01-28 02:00:02","rate":"0.1898"}';
$array = json_decode($string, true);
$str = json_encode(array_values($array));
echo str_replace('"', '', $str);
you should try this
$str ='{"updated":"2016-01-28 02:00:02","rate":"0.1898"}';
$data=json_decode($str);
echo '<pre>';
echo 'json decode it returns ojbects<br>';
print_r($data);
echo 'convert object into array<br>';
$data=(array)$data;
print_r($data);
echo 'Your Output<br>';
echo json_encode(array_values($data));

Given an array, find zero values and replace them with the average of immediately bordering values

I have an array of temperature data by hour. Some hours have zero data instead of a temp. When graphing using Google Charts, the zero causes the line graph to plummet. My temporary fix was to replace the zero values with null, causing a break in the line graph. The ideal solution would be to take the values on either side of the zero, and average them. The array is in order by hour. Help?
$array = array(
"1AM" => "65",
"2AM" => "66",
"3AM" => "68",
"4AM" => "68",
"5AM" => "68",
"6AM" => "0",
"7AM" => "70",
"8AM" => "71",
"9AM" => "71",
"10AM" => "73",
);
Here's my script replacing the 0's with nulls:
$array = array ();
foreach($parsed_json->history->observations as $key => $value) {
$temp = (int)$value->tempi;
if ($temp==0) {
str_replace(0, null, $temp);
}
$hour = $value->date->hour;
$array[$hour] = $temp;
};
This Example would work great if the data was mine, but alas, it's from a JSON feed.
Would I use an array_walk() sort of deal? How would I reference the current place in the array? Any help is appreciated!
I would scratch out the null portion, and just foreach-loop through the final array.
So, change your current code to:
$array = array ();
foreach($parsed_json->history->observations as $key => $value) {
$temp = (int)$value->tempi;
}
$hour = $value->date->hour;
$array[$hour] = $temp;
And add this below it:
foreach($array as $hour => $temp){
if($temp == "0"){
$numHour = $hour[0];
$hourPlus = ($numHour + 1) . "AM";
$hourMinus = ($numHour - 1) . "AM";
$valuePlus = $array[$hourPlus];
$valueMinus = $array[$hourMinus];
$average = ($valuePlus + $valueMinus)/2;
$array[$hour] = $average;
}
}
?>
This of course assumes that the values on either side of the zero are also not zero. You may want to add a check for that somewhere in there.
Tested and proven method.
Couldn't you do something along the lines of:
str_replace(0, ((($key-1)+($key+1))/2), $temp);
Where $key is array position, take the value before 0 and after 0 add them and divide them by 2 to get the average.
I'll let you sort out what happens if first, last or consecutive values are 0.
$the_keys=array_keys($array);
foreach($the_key as $index=>$key)
{
if($array[$key]==0)
{
$array[$key]=($array[$the_key[$index-1]]+$array[$the_key[$index+1]]/2);
}
}

Categories