0

I am following a tutorial that uses a foreach statement to loop through a json file. Of course in the example I am following this works fine, but I can't seem to get it to work on my version. I think that the error is indicating that I am not actually passing an array. Does that mean the issue is in the json file? Or is there a syntax issue?

Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\loops\json_example.php on line 27

JSON FILE: movies.json

{ //json object
"movies": [ //movies = array
    {
        "title": "The Godfather",
        "year": "1972",
        "genre": "Drama",
        "director": "Francis Ford Copolla"
    },
    {
        "title": "Superbad",
        "year": "2007",
        "genre": "Comedy",
        "director": "Greg Mottola"
    },
    {
        "title": "The Departed",
        "year": "2006",
        "genre": "Drama",
        "director": "Martin Scorsese"
    },
    {
        "title": "Saving Private Ryan",
        "year": "1998",
        "genre": "Action",
        "director": "Steven Spielberg"
    },
    {
        "title": "The Expendables",
        "year": "2010",
        "genre": "Action",
        "director": "Sylvester Stallone"
    }
]
}

PHP CODE: json_example.php

    <?php
    $jsondata = file_get_contents("movies.json"); #set variable, function "file_get_contents" grabs everything in the file. can also use with a website is url is within () to insert entire site.

    $json = json_decode($jsondata, true); #decodes json so that we can parse it
?>

<!DOCTYPE html>
<html>
<head>
    <title>JSON Example</title>
</head>

<body>
    <div id="container">
        <h1>My Favorite Movies</h1>
        <ul>
            <?php      
                foreach($json['movies'] as $key => $value) {
                    echo '<h4>'.$value['title'].'</h4>';
                    echo '<li>Year: '.$value['year'].'</li>';
                    echo '<li>Genre: '.$value['genre'].'</li>';
                    echo '<li>Director: '.$value['director'].'</li>';
                }
            ?>
        </ul>
    </div>

</body>

</html>

Please excuse my comment notes, I am still learning.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
Jon B
  • 1
  • 1

2 Answers2

0

your json_decode is failing due to bad json format. bad JOSN Format

$test =' { //json object
    "movies": [ //movies = array
        {
            "title": "The Godfather",
            "year": "1972",
            "genre": "Drama",
            "director": "Francis Ford Copolla"
        }]}';

any comments inside json will be treated as json string your json decode fails due bad format

$decode = json_decode($test,TRUE) ; // fails to decode due to bad json if you var_dump($decode) result in null

Remove the comments inside json string

$test =' { 
    "movies": [ 
        {
            "title": "The Godfather",
            "year": "1972",
            "genre": "Drama",
            "director": "Francis Ford Copolla"
        }]}';
  • This was the problem, thank you! In my effort to document what I was learning I didn't realize that with a JSON file, any comments inside are treated as a string. I basically sabotaged myself by trying to be thorough lol. – Jon B Aug 08 '18 at 23:23
0

Invalid argument supplied for foreach()

Means that $json['movies'] that you used in

foreach($json['movies'] as $key => $value) {

Is not an array or object. The PHP documentation states:

foreach works only on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.

Theoretically, $json = json_decode($jsondata, true); should produce an array with a key 'movies' the contains an array of movies, but since you're getting the invalid argument warning, that means that hasn't happened for some reason.

If your movies.json file really does contain comments, that is the reason. As others have stated, JSON cannot contain comments.

If the file doesn't really have comments, or if you remove the comments and still don't get the array you're expecting, you can use json_last_error or json_last_error_msg to help diagnose the problem.

You should include some kind of error handling in your code for cases where the input file can't be parsed for whatever reason. In this case it may be because you unknowingly put comments in it, but in the future if you get the file from some other source, you may not have control of its contents. Just checking if (is_array($json['movies'])) should be sufficient to verify that you have something you can iterate with foreach. How you want to handle situations where you don't is up to you.

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • Thanks for further clarifying how to further diagnose the problem with json_last_error and json_last_error_msg! – Jon B Aug 08 '18 at 23:26