PHP - Parsing nested JSON array values - php

I have hit a wall and I am not sure what is causing this. I am parsing a JSON file and creating variables. All the ones that are not nested in arrays work great. These two below are not though and I am not sure why. $hail var value shows for both the hail and the $wind var and I am completely puzzled as to why.
Here is a snippet of the code to create the variable from the value.
$hail = isset($currFeature['properties']['parameters']['hailSize'][0]);
$wind = isset($currFeature['properties']['parameters']['windGust'][0]);
Here is how it is outputted and displayed in the HTML which it displays but shows $hail for both var.
<div class="alerts-description"> HAZARDS<br /><? if (isset($hail)) {echo $hail . '" Hail';} ?><br /> <? if (isset($wind)) {echo $wind . '" MPH Winds';} ?></div>
Example of array as both hailSize and windGust is nested under parameters and both [0]
[response] => Avoid
[parameters] => Array
(
[hailSize] => Array
(
[0] => 0.50
)
[windGust] => Array
(
[0] => 70
)
[VTEC] => Array
(
[0] => /O.NEW.KFWD.FA.W.0008.170813T1318Z-170813T1615Z/
)
[EAS-ORG] => Array
(
[0] => WXR
)
Any suggestions what I am doing wrong or am missing?
EDIT: Link to example code just hit the "Run it" button"
http://rextester.com/EELE62798
-Thanks!

$hail = isset($currFeature['properties']['parameters']['hailSize'][0]);
The above code will generate a variable with the value true or false. It will never have the value from your data.
The following PHP7 code is a possible solution.
<?php
$json = '{"properties":{"parameters":{"hailSize":[0.50],"windGust":[70]}}}';
$currFeature = json_decode($json, true);
$hail = $currFeature['properties']['parameters']['hailSize'][0] ?? null;
$wind = $currFeature['properties']['parameters']['windGust'][0] ?? null;
// check specifically for null
if ( $hail !== null ) {
echo $hail . '" Hail'. PHP_EOL;
}
// check specifically for null
if ( $wind !== null ) {
echo $wind . '" MPH Winds'. PHP_EOL;
}
if ( empty($currFeature['properties']['parameters']['windGust'][1]) ) {
echo "empty also works to check for missing data\n";
}
if ( ! isset($currFeature['properties']['parameters']['windGust'][1]) ) {
echo "isset to check for missing data\n";
}
If you run it on the command line you will get the following output:
0.5" Hail
70" MPH Winds
empty also works to check for missing data
isset to check for missing data

Related

How do I echo Nested Array Element?

I don't know what I'm doing wrong, I can't get my array item to echo out. I keep getting this error:
Illegal string offset 'CreatedDatetime'.
My XML looks like this via JSON print_r:
Array
(
[ABOUT_VERSIONS] => Array
(
[ABOUT_VERSION] => Array
(
[CreatedDatetime] => 2019-10-22T22:29:47.7617229Z
[DataVersionIdentifier] => 201703
)
)
)
My code is:
foreach ($newArr["ABOUT_VERSIONS"]["ABOUT_VERSION"] as $item){
echo $item["CreatedDatetime"]."<br>";
}
This seems so simple but I'm having a block. I can't echo out the CreatedDatetime key.
$item is not an array, it iterates over the two values in $newArr['ABOUT_VERSION'] i.e. 2019-10-22T22:29:47.7617229Z and 201703. To display the CreatedDatetime, either access it directly:
echo $newArr["ABOUT_VERSIONS"]["ABOUT_VERSION"]["CreatedDatetime"] . "<br>";
or do a key comparison in the loop:
foreach ($newArr["ABOUT_VERSIONS"]["ABOUT_VERSION"] as $key => $value){
if ($key == "CreatedDatetime") echo $value . "<br>";
}
In both cases the output is 2019-10-22T22:29:47.7617229Z.
Demo on 3v4l.org

Extract JSON ouput to get line by line key pair values using PHP

I would like to extract JSON ouput using PHP and tried below code but I'm getting output of single character instead of row wise values. I read similar posts but failed to get key pair values and getting output as single character. Wherever field values won't present, null is ok for that. How can I get output line by line for respective keys?
Tried code:
while (!feof($resultFile)) {
$line = fgets ($resultFile);
echo $line;
$someArray = json_decode($line);
foreach ($someArray as $key => $value) {
echo $value["key"] . ", " . $value["status"] . "<br>";
}
}
someArray output:
Array ( [key] => XYZ-6680 [status] => Open [components] => API [currentVersion] => Release1.2 [expectedVersion] => Array ( ) [customerInfo] => Default Calendar when the delegate responds to those invitations. ) Array ( [key] => XYZ-3325 [status] => Closed [components] => API [currentVersion] => Release 1.0 [expectedVersion] => Array ( [0] => Array ( [self] => https://bug.restify.com/rest/api/2/version/27771 [id] => 27771 [name] => Release1.2 [archived] => [released] => ) ) [customerInfo] => Fixed a number of bugs related to DA: * CrossMailboxSearch: Group label was shown even when all setting items of the group were hidden on New Account dialog ([https://bug.goog.restify/show_bug.cgi?id=1542 Bug 1542]) * After performing a bulk migration, the Delegated Admin user encountered an `HTTP Error 403` when attempting to download the list of provisioned accounts ([https://bug.goog.restify/show_bug.cgi?id=1039 Bug 1039]) ) Array ( [key] => XYZ-223 [status] => Closed [components] => API [currentVersion] => Release 1.3 [expectedVersion] => Array ( [0] => Array ( [self] => https://bug.restify.com/rest/api/2/version/29171 [id] => 29171 [name] => Release1.2 [archived] => [released] => ) ) [customerInfo] => "Default Calendar" user preference, `zimbraPrefDefaultCalendarId`. )
line output:
{"key":"XYZ-6680","status":"Open","components":"API","currentVersion":"Release1.2","expectedVersion":[],"customerInfo":"Default Calendar when the delegate responds to those invitations."} X, X
O, O
A, A
R, R
,
D, D
{"key":"XYZ-3325","status":"Closed","components":"API","currentVersion":"Release 1.0","expectedVersion":[{"self":"https://bug.restify.com/rest/api/2/version/27771","id":"27771","name":"Release1.2","archived":false,"released":false}],"customerInfo":"Fixed a number of bugs related to DA: * CrossMailboxSearch: Group label was shown even when all setting items of the group were hidden on New Account dialog ([https://bug.goog.restify/show_bug.cgi?id=1542 Bug 1542]) * After performing a bulk migration, the Delegated Admin user encountered an `HTTP Error 403` when attempting to download the list of provisioned accounts ([https://bug.goog.restify/show_bug.cgi?id=1039 Bug 1039])"} X, X
C, C
A, A
R, R
,
F, F
{"key":"XYZ-223","status":"Closed","components":"API","currentVersion":"Release 1.3","expectedVersion":[{"self":"https://bug.restify.com/rest/api/2/version/29171","id":"29171","name":"Release1.2","archived":false,"released":false}],"customerInfo":"\"Default Calendar\" user preference, `zimbraPrefDefaultCalendarId`."}X, X
C, C
A, A
R, R
,
", "
JSON (resultFile content):
{"key":"XYZ-6680","status":"Open","components":"API","currentVersion":"Release1.2","expectedVersion":[],"customerInfo":"Default Calendar when the delegate responds to those invitations."}
{"key":"XYZ-3325","status":"Closed","components":"API","currentVersion":"Release 1.0","expectedVersion":[{"self":"https://bug.restify.com/rest/api/2/version/27771","id":"27771","name":"Release1.2","archived":false,"released":false}],"customerInfo":"Fixed a number of bugs related to DA: * CrossMailboxSearch: Group label was shown even when all setting items of the group were hidden on New Account dialog ([https://bug.goog.restify/show_bug.cgi?id=1542 Bug 1542]) * After performing a bulk migration, the Delegated Admin user encountered an `HTTP Error 403` when attempting to download the list of provisioned accounts ([https://bug.goog.restify/show_bug.cgi?id=1039 Bug 1039])"}
{"key":"XYZ-223","status":"Closed","components":"API","currentVersion":"Release 1.3","expectedVersion":[{"self":"https://bug.restify.com/rest/api/2/version/29171","id":"29171","name":"Release1.2","archived":false,"released":false}],"customerInfo":"\"Default Calendar\" user preference, `zimbraPrefDefaultCalendarId`."}
Expected output:
Line by line values of key, status, components, currentVersion, expectedVersion, customerInfo.
Actual output:
First of all, #Curious_mind is right about forcing output of json_decode as an associative array with second parameter to true. Then I think you should get what you want by echoing directly $key and $value, like so:
while (!feof($resultFile)) {
$line = fgets ($resultFile);
echo $line;
$someArray = json_decode($line,true);
foreach ($someArray as $key => $value) {
echo key . ", " . $value . "<br/>";
}
}
BUT, careful, if $value is an array, you will get an error (can't just echo an array), so you need to handle the array resulting of you json recusivly.
I adapt the function found here: Echo a multidimensional array in PHP
and added some testing to display string for boolean value too.
It should display the json values as you wish:
while (!feof($resultFile)) {
$line = fgets ($resultFile);
//echo $line;
$someArray = json_decode($line,true);
RecursiveWrite($someArray);
}
function RecursiveWrite($array) {
foreach ($array as $key => $value) {
echo $key .', ';
if(is_array($value)) {
echo "<br>";
RecursiveWrite($value);
}
elseif(is_bool($value)) {
echo ($value? 'true' : 'false') . "<br>";
}
else {
echo $value . "<br>";
}
}
}
How about that $someArray = json_decode($line,true);? because without the 2nd parameter true, json_decode() will return results as object and for that case you've to use $value->key while accessing keys not $value['key']
while (!feof($resultFile)) {
$line = fgets ($resultFile);
echo $line;
$someArray = json_decode($line,true); # see the tweak here
foreach ($someArray as $key => $value) {
echo $value["key"] . ", " . $value["status"] . "<br/>";
}
}
First I agree with Dexter0015's answer. It should be marked as the correct answer as it will deal with a wide variety of results.
I just thought I'd throw my two cents in for a shorter and very problem specific to the user's issue.
/* Load up a record that is json encoded */
$json = '{"key":"XYZ-6680","status":"Open","components":"API","currentVersion":"Release1.2","expectedVersion":[],"customerInfo":"Default Calendar when the delegate responds to those invitations."}';
/* Use json_decode to convert the JSON string to a PHP Array. Be sure and set the second parameter to true in json_decode to get an array and not an object */
$array = json_decode($json, true);
/*
* Now iterate through the result extracting the key and value of the array created from json decode
* There could be instances (expectedVersion) that may have an array of values. So test to see
* if the array value is an array. If so using print_r, otherwise just echo out the $value as a string
*/
foreach ($array as $key => $value) {
if (!is_array($value)) {
echo '* Key ' . $key . ' has a value of :' . $value . PHP_EOL;
} else {
echo "* Key " . $key . ' has an array of values :' . print_r($value, true) . PHP_EOL;
}
}

How to parse JSON with PHP

I need help with something..
How can I parse data in this format: https://api.coinmarketcap.com/v1/ticker/
I tried set up a code in php
$url = 'https://api.coinmarketcap.com/v1/ticker/';
$content = file_get_contents($url);
$json = json_decode($content, true);
print_r($json);
This will list all the values like this..
Array ( [0] => Array ( [id] => bitcoin [name] => Bitcoin [symbol] =>
BTC [rank] => 1 [price_usd] => 2448.04 [price_btc] => 1.0
[24h_volume_usd] => 1935820000.0 [market_cap_usd] => 40128026876.0
[available_supply] => 16391900.0 [total_supply] => 16391900.0
[percent_change_1h] => 3.47 [percent_change_24h] => -11.1
[percent_change_7d] => -12.29 [last_updated] => 1497512954 ) [1] =>
Array ( [id] => ...
How can I access certain values. For example if I want to display "name and symbol"?
The idea is to put name+symbol in select (dropdown) list, and when user changes selection, text field beside dropdown list automatically changes and shows properly market_cap_usd value.
I was able to go forward and parse some data..
foreach ($json as $key => $value) {
foreach ($value as $valuta => $vrednost) {
echo "<p>$valuta | $vrednost</p>";
}
}
I have in mind that this is not the best way.. Do I need to create object (how?) so I could call "name" value directly or something else...
EDIT:
I find a solution for my problem with accessing values. I was also able to put those values to select/dropdownmenu element.
Here is my version:
<form>
<label for="sel1">Select list (select one):</label>
<select class="selectpicker" data-live-search="true">
<?php
$url = 'https://api.coinmarketcap.com/v1/ticker/';
$content = file_get_contents($url);
$json = json_decode($content, true);
foreach ($json as $key => $value) {
echo "<option>" . $json[$key]['name'] ." (". $json[$key]['symbol'] .")</option>";
}
?>
</select>
</form>
Maybe will someone find some useful thing here for their own "problems".
What is missing for me right now is the connection between selection in dropdown and displaying correct value beside, based on that selection.
For your case, you'll need this code. I changed variable names to be more self-explaining.
$url = 'https://api.coinmarketcap.com/v1/ticker/';
$content = file_get_contents($url);
$decodedData = json_decode($content, true);
foreach ($decodedData as $currency) {
echo "<option value='" . $currency["id"] . "'>" . $currency["name"] ." (". $currency["symbol"] .")</option>";
}
What json_decode does is that it converts a JSON string into a multidimensional array in PHP. Then, you can iterate over it using foreach.
Hey use the code below.
<?PHP
$url = 'https://api.coinmarketcap.com/v1/ticker/';
$content = file_get_contents($url);
$json = json_decode($content, true);
echo $json[0]["bitcoin"];
?>

php- popping a value from array returns wrong result

Ok, I will explain what I am trying to implement here. It's like a number search. I will pass a number and server returns an array of all number. If the passed number is present, I will have to pop that number from the array.
It works, but not in all scenarios.
<?php
function fetchAll()
{
$data= array();
$motherArray='["1","48","2","44","4"]';
$data = json_decode($motherArray);
return $data;
}
$allIDs=fetchAll();
if (!empty($allIDs))
{
$checkThis=4;
if(in_array($checkThis,$allIDs))
{
if (($key = array_search($checkThis, $allIDs)) !== false)
{
unset($allIDs[$key]);
}
if(!empty($allIDs))
{
$allIDsJSON = json_encode($allIDs);
echo $allIDsJSON;
}
else
{
echo 'empty';
}
}
else
{
echo 'not present';
}
}
?>
Above given is my code. I'm trying to search for the number 4.
Number 4 can be in any position. It can be in first, middle or the last. My code works if the number is in last position. Then, it returns the correct output.
Case 1:
$motherArray='["1","48","2","44","4"]';
if it is in last position, I get the correct output:
["1","48","2","44"]
Case 2:
If number 4 is in any other position
$motherArray='["1","48","2","4","44"]';
then the output I get is:
{"0":"1","1":"48","2":"2","4":"44"}
I don't know why it is happening like that.
Can anyone help me figure out what's wrong with this code?
You're code won't work if there is multiple value of your number:
foreach (array_keys($allIDs, $checkThis) as $key)
unset($allIDs[$key]);
The correct answer is provided in the comments already.I will just add it here with some explanation.
If number is not in last position then when you unset($allIDs[$key]); you create an array that is not sequential.
Original array:
Array ( [0] => 1 [1] => 48 [2] => 2 [3] => 4 [4] => 44 )
Array after unsetting third element: Array ( [0] => 1 [1] => 48 [2] => 2 [4] => 44 )
Because in javascript there are not associative arrays when you use json_encode($allIDs); the valid JSON result you get is a JSON object not an array.
So if you want an array you have to reindex the array yourself like that:
$indexed_array = array();
foreach ($allIDs as $row) {
$indexed_array[] = $row;
}
json_encode($indexed_array);
Or by using array_values function
echo json_encode(array_values($allIDs))

How to search array for duplicates using a single array?

I am checking a list of 10 spots, each spot w/ 3 top users to see if a user is in an array before echoing and storing.
foreach($top_10['top_10'] as $top10) //loop each spot
{
$getuser = ltrim($top10['url'], " users/" ); //strip url
if ($usercount < 3) {
if ((array_search($getuser, $array) !== true)) {
echo $getuser;
$array[$c++] = $getuser;
}
else {
echo "duplicate <br /><br />";
}
}
}
The problem I am having is that for every loop, it creates a multi-dimensional array for some reason which only allows array_search to search the current array and not all combined. I am wanting to store everything in the same $array. This is what I see after a print_r($array)
Array ( [0] => 120728 [1] => 205247 ) Array ( [0] => 232123 [1] => 091928 )
There seems to be more to this code. As there are variables being called in it that aren't defined, such as $c, $usercount, etc.. And using array_search with the 2nd parameter of $array if it doesn't exist is not a good idea also. Since it seems like $array is being set within the if statement for this only.
And you don't seem to be using the $top10 value within the foreach loop at all..., why is this?
It would help to see more of the code for me to be able to help you.

Categories