491

I tried to parse a JSON file using PHP. But I am stuck now.

This is the content of my JSON file:

{
    "John": {
        "status":"Wait"
    },
    "Jennifer": {
        "status":"Active"
    },
    "James": {
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
    }
}

And this is what I have tried so far:

<?php

$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string, true);

echo $json_a['John'][status];
echo $json_a['Jennifer'][status];

But because I don't know the names (like 'John', 'Jennifer') and all available keys and values (like 'age', 'count') beforehand, I think I need to create some foreach loop.

I would appreciate an example for this.

7
  • 65
    You're on the right track. Look up the syntax for foreach (you should get keys and values). Don't give up yet! Commented Dec 3, 2010 at 8:12
  • 11
    @Stefan Mai: foreach($variable as $key => $val) should be what you want :-) Commented Dec 3, 2010 at 8:15
  • Side note: I suggest you configure your PHP setup to display all kind of error messages, including notices Commented Dec 3, 2010 at 8:39
  • Can you elaborate on what you're trying to get out of "parsing" the JSON: i.e. what task are you trying to accomplish with your code (like: "output all statuses", "find names where status is xyz", "find all information for xyz")? Commented Dec 3, 2010 at 10:43
  • X-Ref: How do I extract data from JSON with PHP? (for more finicky array traversion). Commented Feb 4, 2018 at 11:12

16 Answers 16

355

To iterate over a multidimensional array, you can use RecursiveArrayIterator

$jsonIterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(json_decode($json, TRUE)),
    RecursiveIteratorIterator::SELF_FIRST);

foreach ($jsonIterator as $key => $val) {
    if(is_array($val)) {
        echo "$key:\n";
    } else {
        echo "$key => $val\n";
    }
}

Output:

John:
status => Wait
Jennifer:
status => Active
James:
status => Active
age => 56
count => 10
progress => 0.0029857
bad => 0

run on codepad

Sign up to request clarification or add additional context in comments.

7 Comments

Does this approach offer any special advantage over good old foreach?
@Álvaro obviously. With foreach you can only recurse one level of depth. With the above approach you can recurse over a multilevel array. Plus, the entire thing is capsuled in OOP, so you have better reuse and you can easily mock it in UnitTests plus you can stack Iterators with other iterators doing different things, like limiting, caching, filtering and so on.. in addition to any custom iterators you might want to create.
alright, I hadn't considered that nesting level was variable. In such case, this is cleaner than a recursive function.
This style parsing, though, leaves some ambiguity. For example {'John':{'status':'waiting', 'Mary':{'status','nested'}}, 'Suzy':{'status:'waiting'} } is indistinguishable from {'John':{'status':'waiting'}, 'Mary':{'status','nested'}, 'Suzy':{'status:'waiting'} }. That Mary is a structural child of John is lost.
@Jesse php.net/manual/en/class.recursiveiteratoriterator.php would allow you to detect the depth.
|
163

I can't believe so many people are posting answers without reading the JSON properly.

If you foreach iterate $json_a alone, you have an object of objects. Even if you pass in true as the second parameter, you have a two-dimensional array. If you're looping through the first dimension you can't just echo the second dimension like that. So this is wrong:

foreach ($json_a as $k => $v) {
   echo $k, ' : ', $v;
}

To echo the statuses of each person, try this:

<?php

$string = file_get_contents("/home/michael/test.json");
if ($string === false) {
    // deal with error...
}

$json_a = json_decode($string, true);
if ($json_a === null) {
    // deal with error...
}

foreach ($json_a as $person_name => $person_a) {
    echo $person_a['status'];
}

?>

4 Comments

If the php and json files are in the same dir, we can read json with file_get_contents("test.json"); (No need to put the path).
@Chetabahana That's actually not correct. If you use a relative path like test.json, then the path is evaluated relative to the current directory, not necessarily where the PHP script is. On bash, you can discover the current directory by typing pwd.
@Flimm If the PHP and JSON and execution occur on the same directory, there is no need to specify the absolute path of JSON file. Correct?
@Nguaial That depends on what the current working directory is. For example, let's say you have a PHP file /home/user/project/test.php and a JSON file /home/user/project/json.json. If your current working is /home/user, then to run the PHP file you would type php project/test.php. In this case, the PHP file would need to refer to the JSON file as project/test.json as relative paths are relative to the current working directory, not necessarily to the parent directory of the PHP file.
62

The most elegant solution:

$shipments = json_decode(file_get_contents("shipments.js"), true);
print_r($shipments);

Remember that the json-file has to be encoded in UTF-8 without BOM. If the file has BOM, then json_decode will return NULL.

Alternatively:

$shipments = json_encode(json_decode(file_get_contents("shipments.js"), true));
echo $shipments;

4 Comments

Pretty awesome, but the whole Bill Of Materials (BOM) thing has me totally confused. er... what are you talking about? Am I the only guy miffed at the used of mystery unexplained abbreviations? Okay to use abbreviations, but please explain When First Used (WFU)... thanks.
BOM = byte order mark.
en.wikipedia.org/wiki/Byte_order_mark Typical gotcha if you're working with json on both mac and pc, since they use different default text formats.
This post does not attempt to answer the posted question
43

Try

<?php
$string = file_get_contents("/home/michael/test.json");
$json_a = json_decode($string,true);

foreach ($json_a as $key => $value){
  echo  $key . ':' . $value;
}
?>

3 Comments

Try This answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
As proven by BoltClock's answer, this answer is incorrect for the question's sample data.
how does it iterate the nested multi dim array
20

It's completely beyond me that no one pointed out that your begining "tags" are wrong. You're creating an object with {}, while you could create an array with [].

[ // <-- Note that I changed this
    {
        "name" : "john", // And moved the name here.
        "status":"Wait"
    },
    {
        "name" : "Jennifer",
        "status":"Active"
    },
    {
        "name" : "James",
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
    }
] // <-- And this.

With this change, the json will be parsed as an array instead of an object. And with that array, you can do whatever you want, like loops etc.

5 Comments

You are right for pointing out the array thing.
Oh mine. I should add that you seem to have removed the key in the OP's json while converting to array. So the OP is right.
"But because I don't know the names (like John, Jennifer) and all available keys". He seems to not know the keys, so the only way to traverse the collection is a loop. This kind of tells me he does not direct access to the values by key.
This post fails to answer the question of how to parse a json string and access subarray elements from unknown first level keys. This is Not An Answer and should be a comment under the question. It almost looks like you are recommending that the file should be read, then mutated by string functions to suit your preference. I don't get it.
No, I'm pointing out the structure of the file is wrong for the purpose he is reading it. And therefore it does answer the question. And it indeed seems you don't get it, because I said nothing about string functions. That is just silly.
16

Try This

    $json_data = '{
    "John": {
        "status":"Wait"
    },
    "Jennifer": {
        "status":"Active"
    },
    "James": {
        "status":"Active",
        "age":56,
        "count":10,
        "progress":0.0029857,
        "bad":0
      }
     }';

    $decode_data = json_decode($json_data);
    foreach($decode_data as $key=>$value){

            print_r($value);
    }

2 Comments

Try This answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
The OP asks for parsing data from JSON file, not JSON from variable inside your code.
9

Try:

$string = file_get_contents("/home/michael/test.json");
$json = json_decode($string, true);

foreach ($json as $key => $value) {
    if (!is_array($value)) {
        echo $key . '=>' . $value . '<br />';
    } else {
        foreach ($value as $key => $val) {
            echo $key . '=>' . $val . '<br />';
        }
    }
}

1 Comment

Try This answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
9

More standard answer:

$jsondata = file_get_contents(PATH_TO_JSON_FILE."/jsonfile.json");

$array = json_decode($jsondata,true);

foreach($array as $k=>$val):
    echo '<b>Name: '.$k.'</b></br>';
    $keys = array_keys($val);
    foreach($keys as $key):
        echo '&nbsp;'.ucfirst($key).' = '.$val[$key].'</br>';
    endforeach;
endforeach;

And the output is:

Name: John
 Status = Wait
Name: Jennifer
 Status = Active
Name: James
 Status = Active
 Age = 56
 Count = 10
 Progress = 0.0029857
 Bad = 0

3 Comments

or can say $data = json_decode(file_get_contents("db.json"), true); for first line
Code-only answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
It makes no sense to call array_keys() here when the following foreach() loop can provide the data all by itself. I don't think I agree with "more standard", and I can think of a few better variable names versus $val.
8

Loop through the JSON with a foreach loop as key-value pairs. Do type-checking to determine if more looping needs to be done.

foreach($json_a as $key => $value) {
    echo $key;
    if (gettype($value) == "object") {
        foreach ($value as $key => $value) {
          # and so on
        }
    }
}

1 Comment

Or better yet, know what the structure is beforehand.
8
<?php
$json = '{
    "response": {
        "data": [{"identifier": "Be Soft Drinker, Inc.", "entityName": "BusinessPartner"}],
        "status": 0,
        "totalRows": 83,
        "startRow": 0,
        "endRow": 82
    }
}';
$json = json_decode($json, true);
//echo '<pre>'; print_r($json); exit;
echo $json['response']['data'][0]['identifier'];
$json['response']['data'][0]['entityName']
echo $json['response']['status']; 
echo $json['response']['totalRows']; 
echo $json['response']['startRow']; 
echo $json['response']['endRow']; 

?>

2 Comments

Code-only answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
Rather than ignoring the sample data provided by the OP, please attempt to answer the question in a way that will immediately and directly relate to the posted question.
3

Try it:

foreach ($json_a as $key => $value)
 {
   echo $key, ' : ';
   foreach($value as $v)
   {
       echo $v."  ";
   }
}

1 Comment

Try This answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
1

When you decode a json string, you will get an object. not an array. So the best way to see the structure you are getting, is to make a var_dump of the decode. (this var_dump can help you understand the structure, mainly in complex cases).

<?php
     $json = file_get_contents('/home/michael/test.json');
     $json_a = json_decode($json);
     var_dump($json_a); // just to see the structure. It will help you for future cases
     echo "\n";
     foreach($json_a as $row){
         echo $row->status;
         echo "\n";
     }
?>

Comments

1
$json_a = json_decode($string, TRUE);
$json_o = json_decode($string);



foreach($json_a as $person => $value)
{
    foreach($value as $key => $personal)
    {
        echo $person. " with ".$key . " is ".$personal;
        echo "<br>";
    }

}

1 Comment

Hiya, this may well solve the problem... but it'd be good if you could edit your answer and provide a little more explanation about how and why it works :) Don't forget - there are heaps of newbies on Stack overflow, and they could learn a thing or two from your expertise - what's obvious to you might not be so to them.
0

The quickest way to echo all json values is using loop in loop, the first loop is going to get all the objects and the second one the values...

foreach($data as $object) {

        foreach($object as $value) {

            echo $value;

        }

    }

Comments

-1

You have to give like this:

echo  $json_a['John']['status']; 

echo "<>"

echo  $json_a['Jennifer']['status'];

br inside <>

Which gives the result :

wait
active

2 Comments

Do Like This answers are low value on StackOverflow because they do very little to educate the OP and future researchers. If you are going to leave this answer on the page, please explain how your answer works and why it is advisable.
This answer appears to misunderstand the question. The OP doesn't know the "name" keys in advance, so they cannot be hardcoded. This answer is incorrect.
-1

I am using below code for converting json to array in PHP, If JSON is valid then json_decode() works well, and will return an array, But in case of malformed JSON It will return NULL,

<?php
function jsonDecode1($json){
    $arr = json_decode($json, true);
    return $arr;
}

// In case of malformed JSON, it will return NULL
var_dump( jsonDecode1($json) );
?>

If in case of malformed JSON, you are expecting only array, then you can use this function,

<?php
function jsonDecode2($json){
    $arr = (array) json_decode($json, true);
    return $arr;
}

// In case of malformed JSON, it will return an empty array()
var_dump( jsonDecode2($json) );
?>

If in case of malformed JSON, you want to stop code execution, then you can use this function,

<?php
function jsonDecode3($json){
    $arr = (array) json_decode($json, true);

    if(empty(json_last_error())){
        return $arr;
    }
    else{
        throw new ErrorException( json_last_error_msg() );
    }
}

// In case of malformed JSON, Fatal error will be generated
var_dump( jsonDecode3($json) );
?>

4 Comments

empty() is unnecessary overhead. Just use !json_last_error(). Furthermore, this fails to answer the question asked by the OP. It is not "How to cast values as arrays" and it is not "how to check for JSON errors". I am flagging this post as Not An Answer.
But no one addressed the case for if json is malformed, so only json_decode() is not enough, should check for valid json also, its your thinking man, marked if u want, I am not here to earn points, as a developer only solution is not enough, pros n cons also,
Every answer is expected to answer the exact question asked. If every answer bled out to associated subject matter, Stackoverflow pages would be much harder for researchers to find the solutions that they are actually hunting. Sometimes I pack my answers with error checking (commonly with my mysql answers) because it is a reasonable accompaniment to a correct solution. I would never purely post error instructions on a "How do I CROSS JOIN" question, for example, because that would not answer the posted question. Do you see now why your post is inappropriate? It has lost sight of the question.
You have posted the correct answer to the wrong question. Better places may include: stackoverflow.com/q/2348152/2943403 or stackoverflow.com/q/6041741/2943403 or stackoverflow.com/q/5970270/2943403 and many, many more.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.