1

So the JSON object I'm trying to reach sometimes does not exist.

Notice: Undefined index: movies in C:\xampp\htdocs\example\game.php

I'm reaching for it in the Steam API with this code on game.php:

$GLOBALS['gameTrailer'] = $game_json[$trimmed]['data']['movies'][0]['webm']['max'];

echo json_encode(array(
    'gameTrailer' => $GLOBALS['gameTrailer'],
    //+ other variables
));

I'm using AJAX to poke game.php like so on index.php:

function returnGame () {
            $.ajax({
              url: "game.php",
              type: "post",
              dataType: 'json',
              success: function(data){
                  console.log(data);

                  $('#video').removeAttr('src');

                  ///// Game name /////
                  $('#gameName').html(data.gameName);
                  /////////////////////                   

                  ////// Append and load video /////
                  var videoSrc = data.gameTrailer;
                  var video_block = $('#video');
                  if (videoSrc !== null && videoSrc !== undefined) {
                        video_block.load();
                        document.querySelector('video').src = videoSrc;
                  } else {
                      $("#gameTrailer").find("#gameScreenshot").attr("src", data.gameScreenshot);
                  }
                  //////////////////////////////////
              },  
            }); 
        }

When movies is null, the AJAX function does nothing. The video does not change to blank, and the movie title is not updated to something new. When movies is not undefined, it works perfectly.

I can't seem to catch $GLOBALS['gameTrailer'] as undefined and re-iterate or replace with screenshot instead of movie though, not on game.php or index.php. I've tried things like if(empty()) {} and if($GLOBALS['gameTrailer'] == NULL) {}, but even though the error code on game.php tells me that it is undefined, it seems to act like it's not.

Any ideas will be much appreciated. Thanks.

EDIT: Full game.php code:

<?php

if(isset($_POST)) {
    fetchGame();
}

function fetchGame() {
    ////////// ID-picker //////////
    $f_contents = file("steam.txt");
    $url = $f_contents[mt_rand(0, count($f_contents) - 1)];             
    $answer = explode('/',$url);
    $gameID = $answer[4];
    $trimmed = trim($gameID);

    ////////// Fetch game //////////
    $json = file_get_contents('http://store.steampowered.com/api/appdetails?appids='.$trimmed);
    $game_json = json_decode($json, true);

    ////////// Store variables //////////
    $GLOBALS['gameName'] = $game_json[$trimmed]['data']['name'];
    $GLOBALS['gameTrailer'] = $game_json[$trimmed]['data']['movies'][0]['webm']['max'];
    $GLOBALS['gameScreenshot'] = $game_json[$trimmed]['data']['screenshots'][0]['path_full'];
    $GLOBALS['gameImage'] = $game_json[$trimmed]['data']['header_image'];
    $GLOBALS['gameId'] = $trimmed;
    $GLOBALS['free'] = $game_json[$trimmed]['data']['is_free'];
    $GLOBALS['price'] = $game_json[$trimmed]['data']['price_overview']['final'];

    if(!isset($GLOBALS['price']) && ($GLOBALS['gameTrailer'])) {
        fetchGame();
    }

    if ($GLOBALS['free'] === TRUE) {
        $GLOBALS['final_price'] = "Free";
    } elseif($GLOBALS['free'] === FALSE || $GLOBALS['final_price'] != NULL) {
        $GLOBALS['final_price'] = $GLOBALS['price'];
    } else {
        $GLOBALS['final_price'] = "-";
    }
}

////////// Return to AJAX (index.php) //////////
echo 
    json_encode(array(
        'gameName' => $GLOBALS['gameName'],
        'gameTrailer' => $GLOBALS['gameTrailer'],
        'gameImage' => $GLOBALS['gameImage'],
        'gameId' => $GLOBALS['gameId'],
        'finalPrice' => $GLOBALS['final_price'],
        'gameScreenshot' => $GLOBALS['gameScreenshot']
    ))
;

?>

It breaks on line 23 ($GLOBALS['gameTrailer'] = $game_json[$trimmed]['data']['movies'][0]['webm']['max']; as an undefined index)

Chris
  • 6,272
  • 9
  • 35
  • 57
Algernop K.
  • 477
  • 2
  • 19
  • `array_key_exists` is used for such purposes. – lolbas May 04 '16 at 12:39
  • Or `isset` I find is more commonly used. – Jonnix May 04 '16 at 12:42
  • @JonStirling depends on OPs' needs. [See difference here.](http://stackoverflow.com/a/700257/3745677) – lolbas May 04 '16 at 12:44
  • So like `if(isset($GLOBALS['gameTrailer'])) { //Return to ajax }`? Alright, but I was sure I'd tried it. I'll give it another go. – Algernop K. May 04 '16 at 12:44
  • @lolbas That's true, though I believe either option will fit the bill in this case. – Jonnix May 04 '16 at 12:46
  • `if(isset($GLOBALS['gameTrailer'])) { // json_encode to AJAX } else { // Re-iterate function }` does not seem to solve my problem. Some clicks just won't reload another movie, nor show up as a failure/attempt in console.log – Algernop K. May 04 '16 at 12:48
  • You haven't provided enough code for us to really comment on that. Provide the full relevant code in a question update please. – Jonnix May 04 '16 at 12:50
  • @JonStirling Well it's not great, so I am a little embarrassed. Just a second though. – Algernop K. May 04 '16 at 12:51
  • @JonStirling O-kay, there I go. I want to re-iterate if it's undefined, but I can't seem to do that – Algernop K. May 04 '16 at 13:01
  • Okay, before I suggest anything, what is this code actually supposed to do? Pick a random game ID, if it doesn't have a video, try a different game? Otherwise send the data back? – Jonnix May 04 '16 at 13:09
  • @JonStirling Yes. $trimmed is a game-id picked from a list of games in a .txt. If the random game-id doesn't have a video on its API page; reiterate and get a new game id and try again. Otherwise, send data to index.php (from where the AJAX call is made) – Algernop K. May 04 '16 at 13:13

1 Answers1

1

Okay, so here is an example update to the code provided going by the comments made on the question.

Notes:

1) Don't use $GLOBALS unless you know what you're doing and why you're using it. In this case, it doesn't appear required. Updated to $game as it's holding game details.

2) You need to check whether something exists before you try and access it. So, the isset you previously had is useless as you've already accessed a non-existing array item. Removed that check.

3) Recursion is good, but again, you need to know what you're doing, and why you're using it. I suspect this was unintentional anyway but was removed as part of 2.

4) You state that having a video (and price by the looks of it) is a requirement for this function, so you should check that up front. Note that the first thing after getting the ID, is to see if there's a video. Why do work just to find we can't use it?

5) You want to try a different game if there is no video, so we wrap the check and assignments in a loop, and continue if the video isn't there. Note that you might want to restrict this to n number of tries otherwise you might end up waiting ages for your script to find a game that has a video, but that's for you to decide.

<?php
if(isset($_POST)) {
    fetchGame();
}

function fetchGame() {
    $gameFound = false;

    while(!$gameFound) {
        ////////// ID-picker //////////
        $f_contents = file("steam.txt");
        $url = $f_contents[mt_rand(0, count($f_contents) - 1)];             
        $answer = explode('/',$url);
        $gameID = $answer[4];
        $trimmed = trim($gameID);

        ////////// Fetch game //////////
        $json =     file_get_contents('http://store.steampowered.com/api/appdetails?appids='.$trimmed);
        $game_json = json_decode($json, true);

        if(!isset($game_json[$trimmed]['data']['movies'][0]['webm']['max']) || !isset($game_json[$trimmed]['data']['price_overview']['final'])) {
            continue;
        }

        $gameFound = true;

        ////////// Store variables //////////
        $game['gameName'] = $game_json[$trimmed]['data']['name'];
        $game['gameTrailer'] = $game_json[$trimmed]['data']['movies'][0]['webm']['max'];
        $game['gameScreenshot'] = $game_json[$trimmed]['data']['screenshots'][0]['path_full'];
        $game['gameImage'] = $game_json[$trimmed]['data']['header_image'];
        $game['gameId'] = $trimmed;
        $game['free'] = $game_json[$trimmed]['data']['is_free'];
        $game['price'] = $game_json[$trimmed]['data']['price_overview']['final'];

        if ($game['free'] === TRUE) {
            $game['final_price'] = "Free";
        } elseif($game['free'] === FALSE || $game['final_price'] != NULL) {
            $game['final_price'] = $game['price'];
        } else {
            $game['final_price'] = "-";
        }
    }
}

////////// Return to AJAX (index.php) //////////
echo 
    json_encode(array(
        'gameName' => $game['gameName'],
        'gameTrailer' => $game['gameTrailer'],
        'gameImage' => $game['gameImage'],
        'gameId' => $game['gameId'],
        'finalPrice' => $game['final_price'],
        'gameScreenshot' => $game['gameScreenshot']
    ));
?>

Note this code is untested, but I hope gives you an idea of how to proceed.

Jonnix
  • 4,121
  • 1
  • 30
  • 31
  • `{"gameName":null,"gameTrailer":null,"gameImage":null,"gameId":null,"finalPrice":null,"gameScreenshot":null}` on all the `json_encode` lines, guessing it's due to them not being global? Should I fit the `json_encode` part within the while loop instead? – Algernop K. May 04 '16 at 13:37
  • Yes, out of scope. It seems to be working having the encode part within the function. Thanks! 1) - Yes, I've been told before. Just seemed appropriate. 2) - Makes perfect sense, but as I'm quite the beginner, it's hard for me to see. 3) - What recursion? :o 4) - That is a great idea indeed, but again, I wouldn't know how to do that, so I'll do it at a later stage! 5) - I know the loop looks a little dangerous, but a game (in my list) without a video is kind of a rare occurence. – Algernop K. May 04 '16 at 13:44
  • Thank you very very much, you're a great teacher. Bringing it down to my level is a challenge. – Algernop K. May 04 '16 at 13:44
  • Happy to be of help :) – Jonnix May 04 '16 at 13:51