views:

559

answers:

2

Hi, guys!

I know how to decode a JSON string with one object with your help from this example http://stackoverflow.com/questions/2543389/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()?
+4  A: 

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
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
Guys, I've corrected my question! Please, help!
ilnur777
Thank you, T.J. Crowder! Now I've got an answer for that thing. ;-)
ilnur777
+1  A: 

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
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
Guys, I've corrected my question! Please, help!
ilnur777