A JSON document can have JSON objects nested inside other JSON objects. JSON objects are key-value pairs and there are different methods you can use to access JSON objects from a nested JSON document. One method is to use recursion just like you access data from a nested array or tree data structure. Another method is to use loops. Let's look at some examples for accessing data a nested JSON document like below.
[{ "id": 1, "name": "Max Adams", "born": "21 Oct 2001", "cars": [ {"make": "Mercedes", "model": "GLS" }, {"make": "Audi", "model": "Q8" } ], "favourite": { "colour": "Blue", "movie": "Toy Story" } }, { "id": 2, "name": "Steven Miller", "born": "28 Jul 2004", "cars": [ {"make": "Tesla", "model": "Model S"} ], "favourite": { "colour": "Red", "movie": "Mulan" } }, { "id": 3, "name": "Daniel James", "born": "18 Dec 2005", "cars": [ {"make": "Bugatti", "model": "Chiron"} ], "favourite": { "colour": "Yellow", "movie": "Frozen", "toy": "Teddy" } }]
Reading JSON
Consider that our example JSON is stored in a file named "persons.txt". Firstly read the contents of the text file into a string variable using the file_get_contents()
function and then use json_decode()
function to convert the JSON string to a PHP variable.
$filepath = './persons.txt'; $json_string = file_get_contents($filepath); $json = json_decode($json_string, true);
Note that the second argument in the json_decode
function is set to true
so that the objects returned will be associative arrays.
For more details on parsing JSON in PHP, read How to parse JSON in PHP
Accessing objects inside a JSON array
To access the objects inside a JSON array, the simplest and easiest method is to use a foreach
loop to iterate through the array elements and fetch the data that you need. For example, to print all the name and id numbers from our example JSON document:
foreach($json_array as $elem) { echo($elem['id']. ", ".$elem['name'] ); echo("<br/>"); }
This will output
2, Steven Miller 3, Daniel James
Accessing Nested objects inside a JSON array
The value of a JSON can be another JSON object. In our example JSON, there are three JSON objects each corresponding to the details about a person. For each person, there is a key named favourite whose value is another JSON object. You can access this inner JSON object just as you access a multidimensional associative array.
To print all the names and corresponding favourite colour.
foreach($json as $elem) { echo( $elem['name']." - ".$elem['favourite']['colour'] ); echo("<br/>"); }
Output:
Max Adams - Blue Steven Miller - Red Daniel James - Yellow
Accessing JSON arrays inside nested JSON
If you have an array inside a nested JSON object then use two foreach
loops to access the inner array element.
To print all the names and corresponding cars.
foreach($json as $elem) { echo( $elem['name']. " : " ); foreach ($elem['cars'] as $car ) { echo($car['make']. ", "); } echo("<br/>"); }
Output
Max Adams : Mercedes, Audi, Steven Miller : Tesla, Daniel James : Bugatti,
Here is another example to print the number of cars each person has.
foreach($json as $elem) { echo( $elem['name'].": ".count($elem['cars'])); echo("<br/>"); }
Output:
Max Adams: 2 Steven Miller: 1 Daniel James: 1
Search a nested JSON by value
So far, we have seen how to access all objects at a particular level. Now we learn how to search a nested JSON for a specific value.
Our first example is to find all people who owns a 'Tesla' from our sample JSON.
$search_val = 'Tesla'; foreach($json as $elem) { foreach ( $elem['cars'] as $car) { if($car['make'] == $search_val) { echo($elem['name']); echo("<br/>"); } } }
Output:
Steven Miller
In the next example, we search for people who like the colour 'Blue'
$search_val = 'Blue'; foreach($json as $elem) { foreach ( $elem['favourite'] as $key => $val) { if ($key == 'colour' && $val == $search_val) { echo($elem['name']); echo("<br/>"); } } }
Output:
Max Adams
Search a nested JSON by key
In this next example we search for a key instead of a value. For example to find the people who has a favourite toy.
$search_key = 'toy'; foreach($json as $elem) { foreach ( $elem['favourite'] as $key => $val) { if ($key == $search_key) { echo($elem['name']." - ".$val); } } }
Output:
Daniel James - Teddy
Recursively getting all keys and values
Now we look at the another method of accessing data from a nested JSON - Recursion. In this method we create a function which calls itself until a certain condition is met.
Let\'s start with a simple code snippet to print all the keys and values in our sample JSON document.
// Define function function print_recursive($arr){ foreach ($arr as $key => $val) { if (is_array($val)) { print_recursive($val); } else { echo("$key = $val <br/>"); } } return; } // Call function print_recursive($json);
In the above code, the print_recursive
function calls itself if the value is an array otherwise prints the key and value.
Output:
id = 1 name = Max Adams born = 18 Dec 2005 make = Mercedes model = GLS make = Audi model = Q8 colour = Blue movie = Toy Story id = 2 name = Steven Miller ... ...
Search by Key OR Value Recursively
You can recursively search for by key or value inside a nested JSON with a slight modification to the code above. All you need is to defina a function that takes two arguments - an array and a Key/Value. You then run the same recursion as before but you have another if
condition to check for the specified key/value.
Here is an example to get all the car models
// Recursive function to search by key function search_recursive_by_key($arr, $searchkey){ foreach ($arr as $key => $val) { if (is_array($val)) { search_recursive_by_key($val, $searchkey); } else { if ($searchkey == $key) { echo("$key ||| $val <br/>"); } } } return; } // Call function with Key as second argument search_recursive_by_key($json, 'model');
Output:
model ||| GLS model ||| Q8 model ||| Model S model ||| Chiron
Similarly, you can search for a value. For example, to find all people born on a particular date.
// Recursive function to search by value function search_recursive_by_value($arr, $searchval){ foreach ($arr as $key => $val) { if (is_array($val)) { search_recursive_by_value($val, $searchval); } else { if ($searchval == $val) { echo("$key :: $val <br/>"); } } } return; } // Call function with value to search as second argument search_recursive_by_value($json, '18 Dec 2005');
Output:
born :: 18 Dec 2005
Search by Key AND Value Recursively
In the previous examples, you searched for a key or value and echo that key-value pair when found. But, most of the time you might want to search for a key or value and echo its Parent node or a different key-value pair. For example, you want to search for a date and echo the name of the person who was born on that date. Or, search for a car and get the people who has that car. Here is the function to do that.
// Recursive function to search by Key and Value function search_recursive_key_value($arr, $searchkey, $searchval, $result=null){ foreach ($arr as $key => $val) { if (is_array($val)) { search_recursive_key_value($val, $searchkey, $searchval, $result); } else { if ($key == $searchkey) { $result = $val; } if ($searchval == $val) { echo("$result => $val <br/>"); } } } return; } // Call function with a key to output and value to search search_recursive_key_value($json, 'name', '28 Jul 2004'); search_recursive_key_value($json, 'make', 'Audi');
Output:
Steven Miller => 28 Jul 2004 Max Adams => Audi
PHP also provides several built-in array functions to get data from a nested JSON, once JSON string is decoded to a PHP object. We will discuss this in the next post.