19

I know how to decode a JSON string with one object with your help from this example How to decode a JSON String

But now I would like to improve decoding JSON string with several objects and I can't understand how to do it.

Here is an example:

{ "inbox": [
  { "firstName": "Brett", "lastName":"McLaughlin" },
  { "firstName": "Jason", "lastName":"Hunter" },
  { "firstName": "Elliotte", "lastName":"Harold" }
 ],
"sent": [
  { "firstName": "Isaac", "lastName": "Asimov" },
  { "firstName": "Tad", "lastName": "Williams" },
  { "firstName": "Frank", "lastName": "Peretti" }
 ],
"draft": [
  { "firstName": "Eric", "lastName": "Clapton" },
  { "firstName": "Sergei", "lastName": "Rachmaninoff" }
 ]
}
  1. How to make just one foreach() to decode above JSON string?
  2. How to detect object's names: inbox, sent or draft on this foreach()?
Community
  • 1
  • 1
ilnur777
  • 1,135
  • 5
  • 16
  • 28
  • json_decode()ing this should give you an array of objects or arrays. Is your question how to extract something from those arrays? – Pekka Apr 01 '10 at 11:56
  • I gave link to the previous my question above and they showed how to decode information from JSON string but with one object. Now I would like to know how to decode JSON string with several objects! And second, I wanna know how to detect from what object the information was read and display it on the page with table like this: Object: programmers First name: ... Last name: ... Object: authors First name: ... Last name: ... Object: musicians First name: ... Last name: ... – ilnur777 Apr 01 '10 at 12:09
  • *"Now I would like to know how to decode JSON string with several objects!"* I've updated my answer to address that. Basically, you *have* multiple objects in your example. And/or: You can't do that. Details in my answer (http://stackoverflow.com/questions/2560096/how-to-decode-a-json-string-with-several-objects-in-php/2560145#2560145). HTH – T.J. Crowder Apr 01 '10 at 12:17
  • Guys, I've corrected my question! Please, help! – ilnur777 Apr 01 '10 at 13:07
  • I understand the question now. You're looking for `foreach ($thing as $name => $value)`, see my new(est) answer. – T.J. Crowder Apr 01 '10 at 13:16

2 Answers2

29

New answer

Re your revised question: foreach actually works with properties as well as with many-valued items (arrays), details here. So for instance, with the JSON string in your question:

$data = json_decode($json);
foreach ($data as $name => $value) {
    // This will loop three times:
    //     $name = inbox
    //     $name = sent
    //     $name = draft
    // ...with $value as the value of that property
}

Within your main loop over the properties, you can use an inner loop to go over the array entries each property points to. So for instance, if you know that each of the top-level properties has an array value, and that each array entry has a "firstName" property, this code:

$data = json_decode($json);
foreach ($data as $name => $value) {
    echo $name . ':'
    foreach ($value as $entry) {
        echo '  ' . $entry->firstName;
    }
}

...will show:

inbox:
  Brett
  Jason
  Elliotte
sent:
  Issac
  Tad
  Frank
draft:
  Eric
  Sergei

Old answer(s)

Begin edit Re your comment:

Now I would like to know how to decode JSON string with several objects!

The example you posted does have several objects, they're just all contained within one wrapper object. This is a requirement of JSON; you cannot (for example) do this:

{"name": "I'm the first object"},
{"name": "I'm the second object"}

That JSON is not valid. There has to be a single top-level object. It might just contain an array:

{"objects": [
    {"name": "I'm the first object"},
    {"name": "I'm the second object"}
]}

...or of course you can give the individual objects names:

{
    "obj0": {"name": "I'm the first object"},
    "obj1": {"name": "I'm the second object"}
}

End edit

Your example is one object containing three properties, the value of each of which is an array of objects. In fact, it's not much different from the example in the question you linked (which also has an object with properties that have array values).

So:

$data = json_decode($json);
foreach ($data->programmers as $programmer) {
    // ...use $programmer for something...
}
foreach ($data->authors as $author) {
    // ...use $author for something...
}
foreach ($data->musicians as $musician) {
    // ...use $musician for something...
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Hm, I guess I gave an incorrect example on my question. Ok, what I really want to do is next: I have JSON string with objects: inbox, sent and draft messages on array. While decoding JSON string using foreach(), I store decoded information to MySQL database. And I have to know the object name to store it on the database with field "folder". I have just one foreach() that decode the whole JSON string with inbox, sent and draft messages. Is it clear now what I want to do? :-) – ilnur777 Apr 01 '10 at 12:25
  • Thank you, T.J. Crowder! Now I've got an answer for that thing. ;-) – ilnur777 Apr 01 '10 at 18:29
8

You can use the json_decode function to decode the JSON string :

$json = <<<JSON
{ "programmers": [
  { "firstName": "Brett", "lastName":"McLaughlin" },
  { "firstName": "Jason", "lastName":"Hunter" },
  { "firstName": "Elliotte", "lastName":"Harold" }
 ],
"authors": [
  { "firstName": "Isaac", "lastName": "Asimov" },
  { "firstName": "Tad", "lastName": "Williams" },
  { "firstName": "Frank", "lastName": "Peretti" }
 ],
"musicians": [
  { "firstName": "Eric", "lastName": "Clapton" },
  { "firstName": "Sergei", "lastName": "Rachmaninoff" }
 ]
}
JSON;

$data = json_decode($json);


Then, to see what the data looks like, you can dump it :

var_dump($data);


And you'll see you have an object containing three arrays, each one containing other sub-objects :

object(stdClass)[1]
  public 'programmers' => 
    array
      0 => 
        object(stdClass)[2]
          public 'firstName' => string 'Brett' (length=5)
          public 'lastName' => string 'McLaughlin' (length=10)
      1 => 
        object(stdClass)[3]
          public 'firstName' => string 'Jason' (length=5)
          public 'lastName' => string 'Hunter' (length=6)
      ...
  public 'authors' => 
    array
      0 => 
        object(stdClass)[5]
          public 'firstName' => string 'Isaac' (length=5)
          public 'lastName' => string 'Asimov' (length=6)
      ...

Which means you know how to access your data.


For example, to display the list of the programmers, you could use :

foreach ($data->programmers as $programmer) {
  echo $programmer->firstName . ' ' . $programmer->lastName . '<br />';
}


Which would get you the following output :

Brett McLaughlin
Jason Hunter
Elliotte Harold
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • Hm, I guess I gave an incorrect example on my question. Ok, what I really want to do is next: I have JSON string with objects: inbox, sent and draft messages on array. While decoding JSON string using foreach(), I store decoded information to MySQL database. And I have to know the object name to store it on the database with field "folder". I have just one foreach() that decode the whole JSON string with inbox, sent and draft messages. Is it clear now what I want to do? :-) – ilnur777 Apr 01 '10 at 12:27