I have JSON that looks like this (shortened for readability):
{
"heroes": [
{
"name": "antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
{
"name": "axe",
"id": 2,
"localized_name": "Axe"
},
{
"name": "bane",
"id": 3,
"localized_name": "Bane"
}
]
}
I have a PHP variable that is equal to one of the three ids. I need to search the JSON for the id and return the localized name. This is what I’m trying so far.
$heroid = $myplayer['hero_id'];
$heroes = file_get_contents("data/heroes.json");
$heroesarray = json_decode($heroes, true);
foreach ($heroesarray as $parsed_key => $parsed_value) {
if ($parsed_value['id'] == $heroid) {
$heroname = $parsed_value['localized_name'];
}
}
Easy. Just use json_decode(). Explanation follows the code at the bottom.
// First set the ID you want to look for.
$the_id_you_want = 2;
// Next set the $json.
$json = <<<EOT
{
"heroes": [
{
"name": "antimage",
"id": 1,
"localized_name": "Anti-Mage"
},
{
"name": "axe",
"id": 2,
"localized_name": "Axe"
},
{
"name": "bane",
"id": 3,
"localized_name": "Bane"
}
]
}
EOT;
// Now decode the json & return it as an array with the `true` parameter.
$decoded = json_decode($json, true);
// Set to 'TRUE' for testing & seeing what is actually being decoded.
if (FALSE) {
echo '<pre>';
print_r($decoded);
echo '</pre>';
}
// Now roll through the decoded json via a foreach loop.
foreach ($decoded as $decoded_array_key => $decoded_array_value) {
// Since this json is an array in another array, we need anothe foreach loop.
foreach ($decoded_array_value as $decoded_key => $decoded_value) {
// Do a comparison between the `$decoded_value['id']` and $the_id_you_want
if ($decoded_value['id'] == $the_id_you_want) {
echo $decoded_value['localized_name'];
}
}
}
Okay, the reason my first try at this did not work—and neither did yours—is your JSON structure was nested one more level deep that what is expected. See the debugging code I have in place with print_r($decoded);? This is the output when decoded as an array:
Array
(
[heroes] => Array
(
[0] => Array
(
[name] => antimage
[id] => 1
[localized_name] => Anti-Mage
)
[1] => Array
(
[name] => axe
[id] => 2
[localized_name] => Axe
)
[2] => Array
(
[name] => bane
[id] => 3
[localized_name] => Bane
)
)
)
First you have an array to begin with which could equate to $decoded[0] and then below that you have another array that equates to $decoded[0]['heroes'] and then in there is the array that contains the values which is structured as $decoded[0]['heroes'][0], $decoded[0]['heroes'][1], $decoded[0]['heroes'][2].
But the key to solving this was the print_r($decoded); which helped me see the larger structure of your JSON.
json_decode() takes a JSON string and (if the second parameter is true) turns it into an associate array. We then loop through this data with a foreach until we find the hero you want.
$json = ''; // JSON string
$data = json_decode($json, true);
foreach($data['heroes'] as $hero) {
if($hero['id'] === 2) {
var_dump($hero['localized_name']);
// Axe
// This will stop the loop, if you want to keep going remove this line
break;
}
}
Related
I'm trying to decode json array to php array using json_decode, but it's displaying a blank page
Here's the json array
[["id":"2","name":"Sam Nju","photo":"1510074080885.jpg","qty":"10","price":"10000.00"],["id":"3","name":"Daniel","photo":"1510074047056.jpg","qty":"0","price":"40000.00"]]
Here's the code to decode json
$json = file_get_contents('http://localhost/example/index.php/destinations/json');
$data = json_decode($json,true);
$names = $data['result'];
echo "<pre>";
echo $names;
print_r($names);
Thanks
For obtaining proper JSON using json_decode() and json_encode() follow these guidelines:
json_decode() :
This function only works with UTF-8 encoded strings.
Returns the value encoded in json in appropriate PHP type. Values true, false and null are returned as TRUE, FALSE and NULL respectively. NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.
The key and value must be enclosed in double quotes single quotes are not valid.
Your JSON:
[["id":"2","name":"Sam Nju","photo":"1510074080885.jpg","qty":"10","price":"10000.00"],["id":"3","name":"Daniel","photo":"1510074047056.jpg","qty":"0","price":"40000.00"]]
apears to be invalid. Arrays use [] while objects use {}.
This is an example of how a proper PHP array structure would look like prior to doing json_encode() (before sending):
// array structure in PHP to get proper JSON
Array ( [0] => Array ( [id] => 2 [name] => Sam Nju [photo] => 1510074080885.jpg [qty] => 10 [price] => 10000.00 ) [1] => Array ( [id] => 3 [name] => Daniel [photo] => 1510074047056.jpg [qty] => 0 [price] => 40000.00 ) )
which was obtained using the following:
json_decode('[{"id":"2","name":"Sam Nju","photo":"1510074080885.jpg","qty":"10","price":"10000.00"},{"id":"3","name":"Daniel","photo":"1510074047056.jpg","qty":"0","price":"40000.00"}]', true)
which would mean doing this:
$myArray = array();
$firstPerson = array();
$secondPerson = array();
$firstPerson['id'] = 2;
$firstPerson['name'] = "Sam Nju";
// ...
$secondPerson['id'] = 3;
$firstPerson['name'] = "Daniel";
// ...
array_push($myArray, $firstPerson);
array_push($myArray, $secondPerson);
// or $myArray[0] = $firstPerson; and $myArray[1] = $secondPerson;
While valid JSON would look like this:
{{"id":"2","name":"Sam Nju","photo":"1510074080885.jpg","qty":"10","price":"10000.00"},{"id":"3","name":"Daniel","photo":"1510074047056.jpg","qty":"0","price":"40000.00"}}
If you are getting the data from a database you might want to use something like this:
$result = mysqli_query($con, "SELECT .... // database query, $con is connection variable
$myArray = array();
while($row = mysqli_fetch_array($result))
{
$tempArray = array();
$tempArray['id'] = $row[0];
$tempArray['name'] = $row[1];
$tempArray['photo'] = $row[2];
// ...
array_push($myArray, $tempArray);
}
// use print_r($myArray); to test it out.
Although your code looks correct, your JSON data is invalid. Objects are enclosed by {}, not []. Replace the JSON with this, and it should work.
[
{
"id": "2",
"name": "Sam Nju",
"photo": "1510074080885.jpg",
"qty": "10",
"price": "10000.00"
},
{
"id": "3",
"name": "Daniel",
"photo": "1510074047056.jpg",
"qty": "0",
"price": "40000.00"
}
]
Also above answer already mentioned it:
Your JSON is invalid. You can check this e.g. with an JSON linter like https://jsonlint.com/
Plus, you're referencing names with $names = $data['result'];. However, in your provided JSON there is no array (or better object), with key "result".
You may look up your PHP's error log file to understand where the problem lies.
I know how to decode a JSON string and get the data from one dimensional array but how to get the data from the nested array?
Below is my code:
$data = json_decode($json);
and below is the JSON return value:
{
"area_metadata": [
{
"name": "A",
"label_location": {
"latitude": 1,
"longitude": 1
}
},
{
"name": "B",
"label_location": {
"latitude": 1,
"longitude": 1
}
}
],
"items": [
{
"update_timestamp": "2017-05-02T09:51:20+08:00",
"timestamp": "2017-05-02T09:31:00+08:00",
},
"locations": [
{
"area": "A",
"weather": "Showers"
},
{
"area": "B",
"weather": "Cloudy"
}
]
}
]}
I had tested:
echo $data->items->locations[0]->area;
but I got this error
Trying to get property of non-object
Also,I tried to convert JSON into array instead of object:
$data = json_decode($json,true);
if (isset($data))
{
foreach ($data->items->locations as $location)
{
if (empty($location["area"])) { continue; }
if ($location["area"] == "A")
{
echo $location["weather"];
}
}
}
but it also not working.
Could anyone can advise which step that I did wrongly?
Thanks!
Edited:
Below is the pastebin link with full JSON content.
https://pastebin.com/cewszSZD
The JSON you provided (in your question) is malformed and using json_decode() on it will result in NULL. Thus nothing will happen when you try to access the decoded object because it doesn't exist.
The full JSON you provided is valid and the reason why your code didn't yield any results is because in items there is an "inner"-array:
(...)
["items"] => array(1) {
[0] => array(4) {
// ^^^^^^^^^^^^^^^^^
["update_timestamp"] => string(25) "2017-05-02T09:21:18+08:00"
["timestamp"] => string(25) "2017-05-02T09:07:00+08:00"
["valid_period"] => array(2) {
["start"] => string(25) "2017-05-02T09:00:00+08:00"
["end"] => string(25) "2017-05-02T11:00:00+08:00"
}
["forecasts"] => array(47) {
[0] => array(2) {
["area"] => string(10) "Ang Mo Kio"
["forecast"] => string(19) "Partly Cloudy (Day)"
}
(...)
You'll have to access that array through key 0, for arrays it will look like this:
$data = json_decode($json, true);
echo $data['items'][0]['forecasts'][0]['area'];
// ^^^
And for objects like this:
$data = json_decode($json);
echo $data->items[0]->forecasts[0]->area;
// ^^^
The second 0 changes the location (the different arrays in the forecasts array).
You can check the output here (array approach) and here (object approach).
It would be easier to help if you post all the JSON data or link to a screenshot of it. Try:
$items[0]['locations'][0]['area'];
Single quotes on strings, no quotes on numbers.
I have two JSON objects and I would like to compare their structure. How can I do it?
Those object are being generated on-the-fly and depending on dynamic content.
Which means that the objects are always different but most of the time have the same structure. I want to be able to catch the changes once they occur.
Example: These two objects should be considered as equal, because both have the same structure: index var and tags array.
{
"index": 0,
"tags": [
"abc"
]
}
{
"index": 1,
"tags": [
"xyz"
]
}
Thoughts?
## You can use this library TreeWalker php .##
TreeWalker is a simple and smal API in php
(I developed this library, i hope it helps you)
It offers two methods
1- Get json difference
2- Edit json value (Recursively)
this method will return the diference between json1 and json2
$struct1 = array("casa"=>1, "b"=>"5", "cafeina"=>array("ss"=>"ddd"), "oi"=>5);
$struct2 = array("casa"=>2, "cafeina"=>array("ss"=>"dddd"), "oi2"=>5);
//P.s
print_r($treeWalker->getdiff($struct1, $struct2))
{
new: {
b: "5",
oi: 5
},
removed: {
oi2: 5
},
edited: {
casa: {
oldvalue: 2,
newvalue: 1
},
cafeina/ss: {
oldvalue: "dddd",
newvalue: "ddd"
}
},
time: 0
}
It's a bit rough, but you get the picture;
$json = '[
{
"index": 0,
"tags": [
"abc"
]
},
{
"index": 1,
"tags": [
"xyz"
]
},
{
"foo": 2,
"bar": [
"xyz"
]
}]';
$array = json_decode($json, true);
$default = array_keys($array[0]);
$error = false;
$errors = array();
foreach ($array as $index => $result):
foreach ($default as $search):
if (!isset($result[$search])):
$error = true;
$errors[] = "Property '{$search}' at entry '{$index}' not found. ";
endif;
endforeach;
endforeach;
if ($error):
echo 'Objects are not the same. ';
foreach ($errors as $message):
echo $message;
endforeach;
endif;
returns:
Objects are not the same. Property 'index' at entry '2' not found. Property 'tags' at entry '2' not found.
You can try to use package https://github.com/coduo/php-matcher
Example: These two objects should be considered as equal, because both have the same structure: index var and tags array.
You can create a "php-matcher pattern" like this:
{
"index": "#integer#",
"tags": "#array#.repeat(\"#string#\")"
}
Then you match your JSONs against this pattern. If you have 2 JSONs and both match this pattern then it means that they are "equal" according to your definition of equality above.
Please see results in "php-matcher sandbox" for the example JSONs you gave:
Example 1 in sandbox
Example 2 in sandbox
Additionally you can use package https://github.com/sebastianbergmann/diff (which you should already have if you have phpunit) to generate a diff when the pattern doesnt match the value.
For example:
use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
...
$valueToCheck = '{
"foo": 0,
"bar": {"one": 1, "two": "2"}
}';
$expectedValuePattern = '{
"foo": "#integer#",
"bar": {"one": 1, "two": 2}
}';
if (!$matcher->match($valueToCheck, $expectedValuePattern)) {
$differ = new Differ(
new UnifiedDiffOutputBuilder(
"Json value is not matching expected format:\n",
true
)
);
$diffOutput = $differ->diff(
\json_encode(\json_decode($expectedValuePattern, true), JSON_PRETTY_PRINT),
\json_encode(\json_decode($valueToCheck, true), JSON_PRETTY_PRINT)
);
var_dump(
$diffOutput
. "\n".$matcher->getError()."\n"
);
} else {
var_dump('OK');
}
it will print:
Json value is not matching expected format:
## -1,7 +1,7 ##
{
- "foo": "#integer#",
+ "foo": 0,
"bar": {
"one": 1,
- "two": 2
+ "two": "2"
}
}
That message with diff is especially helpfull for bigger JSON's to quickly see which element is not matching.
See more ways of usage in README of that package - especially:
https://github.com/coduo/php-matcher#json-matching
https://github.com/coduo/php-matcher#json-matching-with-unbounded-arrays-and-objects
This package is very good to use in automatic tests (for example: phpunit) to assert if JSON from API responses is correct etc - considering that in integration tests there are often many id's, uuid's, datetime's etc which change on each test execution - like database generated id's etc.
I hope it helps :)
You mean by structure, like model array like:
array ( 'index' => int, 'tags' => array() )
If that's what you are trying to get, try this...
$arr1 = array (
array (
'index' => 0,
'tags' => ['abc']
),
array (
'index' => 1,
'tags' => ['xyz']
),
array (
'index' => 2,
'tags' => ['xyz'],
'boom' => 'granade'
),
array (
'index' => 3,
'tags' => 'xyz'
)
);
$holder = array();
$model = array ('index' => 0, 'tags' => array());
for ($i = 0;$i < count($arr1); $i++)
{
$holder = array_diff(array_merge_recursive($arr1[$i], $model), $model);
if (!empty($holder))
{
echo "different structure<br>";
}
else
{
echo "same structure<br>";
// for further validation
/*
$keys = array_keys($model);
if (is_int($arr1[$i][$keys[0]]) && is_array($arr1[$i][$keys[1]]))
echo "same structure<br>";
else
echo "different structure<br>";
*/
}
}
Sample output:
same structure
same structure
different structure
different structure
You can convert the json string to a php array then use the array_diff($arr1,$arr2) function to compare the newly created array with another array
the result is an array containing the elements of the first array that doesn't exist in the other array
example :
<?php
$array1 = '{"name":"myname","age":"40"}';
//convert the obtained stdclass object to an array
$array1 = (array) json_decode($array1);
$array2 = array("name"=>"myname123","age"=>10);
print_r($array2);
$result_array = array_diff($array1,$array2);
if(empty($result_array[0])){
echo "they have the same structure ";
}
?>
I am running a foreach loop to display json results, when certain conditions are met, and would like to sort them by the name field. I am trying usort(), but can't seem to figure it out.
JSON:
{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg",
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg",
}
}
PHP:
$data_json = file_get_contents('data.json');
$data_array = json_decode($data_json, true);
$i = 0;
foreach($data_array as $key => $person){
if($person['title'] == 'some title'){
include('card.php');
if(++$i % 4 === 0) {
echo '<div class="clearfix"></div>'; // inserts a clearfix every 4 cards
}
}
}
So this returns the all the results I expect, but not sorted. I've tried usort() a few different ways, but just fell on my face terribly:) Please help!
use json_decode first to convert to php array, set the flag to TRUE for associative array $myarr = json_decode($array, TRUE)
the try custom usort
// Sort the multidimensional array
usort($myarr, "custom_sort");
// Define the custom sort function
function custom_sort($a,$b) {
return $a['name']>$b['name'];
}
I hope this helps.
Your json is improperly formatted. There's a couple extra commas, one after each JPG item. Removed below.
Then, json_decode the json string to a PHP associative array, and, since you're using the names as json indexes, ksort (key sort) the resulting array.
$json_string = '{
"Shawn Taylor":{
"name":"Shawn Taylor",
"title":"",
"photo_url":"house_165 (1).jpg"
},
"Another Name": {
"name":"Another Name",
"title":"Title is here",
"photo_url":"Person.jpg"
}
}';
$data_array = json_decode($json_string, true);
ksort($data_array);
// the remaining code
A print_r after the ksort displays:
Array
(
[Another Name] => Array
(
[name] => Another Name
[title] => Title is here
[photo_url] => Person.jpg
)
[Shawn Taylor] => Array
(
[name] => Shawn Taylor
[title] =>
[photo_url] => house_165 (1).jpg
)
)
If you need to sort by a nested index, and you want to maintain the associative array, use uasort:
uasort($data_array, 'sort_name_index');
function sort_name_index($a, $b) {
return $a['name'] > $b['name'];
}
I'm trying to decode some basic JSON data from Mintpal.com (https://www.mintpal.com/api)
The raw data looks like:
[
{
"market_id": "152",
"coin": "VeriCoin",
"code": "VRC",
"exchange": "BTC",
"last_price": "0.00008512",
"yesterday_price": "0.00009300",
"change": "-8.47",
"24hhigh": "0.00009450",
"24hlow": "0.00008050",
"24hvol": "13.153",
"top_bid": "0.00008063",
"top_ask": "0.00008591"
}
]
I just want to pull bits off this information out and assign them to variables. I use the below code with another near identical JSON output and it works fine.
//GET MINTPAL JSON DATA
$url = "https://api.mintpal.com/v1/market/stats/VRC/BTC";
$contents = file_get_contents($url);
$json = json_decode($contents);
//GET 'LAST BID' INFO
$lastBid = $json->code;
The previous raw JSON that works with the above code looks exactly the same, except for not being encased in '[...]' as the Mintpal one is.
{
"success": true,
"message": "",
"result": [
{
"MarketName": "BTC-LTC",
"High": 0.01126000,
"Low": 0.01060000,
"Volume": 442.30927821,
"Last": 0.01061100,
"BaseVolume": 4.86528601,
"TimeStamp": "2014-08-27T13:49:03.497",
"Bid": 0.01051801,
"Ask": 0.01061100,
"OpenBuyOrders": 50,
"OpenSellOrders": 116,
"PrevDay": 0.01079000,
"Created": "2014-02-13T00:00:00"
}
]
}
Any ideas on why I can't read the information this time round?
If you either did a var_dump() or a print_r() of your $json variable you should see that it is now an array starting at element 0 containing all the unique json elements.
//GET MINTPAL JSON DATA
$url = "https://api.mintpal.com/v1/market/stats/VRC/BTC";
$contents = file_get_contents($url);
$json = json_decode($contents);
pR($json);
//GET 'LAST BID' INFO
$lastBid = $json->code;
function pR($data){
echo "<pre>";
print_r($data);
echo "</pre>";
}
That yielded:
Array
(
[0] => stdClass Object
(
[market_id] => 152
[coin] => VeriCoin
[code] => VRC
[exchange] => BTC
[last_price] => 0.00008512
[yesterday_price] => 0.00009300
[change] => -8.47
[24hhigh] => 0.00009300
[24hlow] => 0.00008050
[24hvol] => 12.968
[top_bid] => 0.00008065
[top_ask] => 0.00008585
)
)