1

I am using PHP to leverage the YouTube API to build an array of videos and then storing them in a JSON file. The playlist I am scraping the videos from has 143 videos. For some reason my function is generating an array of 150 videos(7 of the videos are duplicates).

$videoArray = array();
function callone($playlistId, $nextpagetoken='') {
  $apikey = 'myapikey';
  $arrContextOptions=array(
    'ssl'=>array(
      'verify_peer'=>false,
      'verify_peer_name'=>false
    ),
  );
  $dur = file_get_contents("https://www.googleapis.com/youtube/v3/playlistItems?playlistId=".urlencode($playlistId)."&part=snippet,contentDetails&maxResults=50&key=$apikey&pageToken=$nextpagetoken", false, stream_context_create($arrContextOptions));
  $youtubeInfo = json_decode($dur, true);
  $videos = $youtubeInfo['items'];
  for($i=0; $i<count($videos); $i++){
    $videoID = $videos[$i]['snippet']['resourceId']['videoId'];
    $thumbnail = $videos[$i]['snippet']['thumbnails']['medium']['url'];
    $title = $videos[$i]['snippet']['title'];
    $date = $videos[$i]['contentDetails']['videoPublishedAt'];

    $videoArray[$i] = array('videoID'=>$videoID, 'thumbnail'=>$thumbnail, 'title'=>$title, 'date'=>$date);
  }
  if(isset($youtubeInfo['nextPageToken'])){
    $videoArray = array_merge($videoArray, callone($playlistId, $youtubeInfo['nextPageToken']));

    unset($youtubeInfo['nextPageToken']);
  }
  return $videoArray;
}

I cannot figure out why 7 of the videos are being duplicated. I tried to use in_array() to prevent videos from being added to the array if the video ID already existed in the array, but that's not working either:

if (!in_array($videoID, $videoArray)) {
    $videoArray[$i] = array('videoID'=>$videoID, 'thumbnail'=>$thumbnail, 'title'=>$title, 'date'=>$date);
}

Any ideas?


I have resolved that issue by using the YouTube video ID as the array key, however now I am not able to parse the JSON.

Here's what the JSON file looks like:

[
    {
        "0nexU4APLY0":{
            "videoID":"0nexU4APLY0","thumbnail":"https:\/\/i.ytimg.com\/vi\/0nexU4APLY0\/mqdefault.jpg","title":"Lorem Ipsum","date":"2020-09-28T18:24:41Z"
        },
        "PIYWT6VkCKI":{
            "videoID":"PIYWT6VkCKI","thumbnail":"https:\/\/i.ytimg.com\/vi\/PIYWT6VkCKI\/mqdefault.jpg","title":"Dolor Sit","date":"2020-09-25T19:42:16Z"
        },
        "LadKEstUlaA":{
            "videoID":"LadKEstUlaA","thumbnail":"https:\/\/i.ytimg.com\/vi\/LadKEstUlaA\/mqdefault.jpg","title":"Emet","date":"2020-09-14T20:25:37Z"
        }
    }
]

I am having trouble parsing the JSON now that the video ID is the key. It seems like it's not being treated as an array in Javascript now. Here is what my getJSON call looks like:

function getResults() {
    $.getJSON('/youtube.json', function(data) {
        console.log(data);
        var count = data[0].length;
        console.log(count);
        $(data[0]).each(function (i, video) {
            console.log(video);
        });
    });
}

I am getting undefined for the count and the .each function is not returning anything.

3
  • 1
    simple suggestion: try using the $videoID as the Key for $videoArray and then check that with a array_key_exists($videoID, $videoArray); Commented Sep 29, 2020 at 20:08
  • 1
    @MiPnamic that worked! Problem is now I can't seem to parse the JSON. Commented Sep 29, 2020 at 21:15
  • @MiPnamic it looks like it is no longer being treated as an array in Javascript when I use $videoID as the key Commented Sep 29, 2020 at 21:23

1 Answer 1

1

It seems like it's not being treated as an array in Javascript now

That's correct. PHP's associative arrays become JavaScript objects when transported via JSON.

The first thing I'd do is tidy up the JSON produced by your PHP. Once you've eliminated the duplicates, you can simplify your response by just storing the values (and not nested within another array)

$videoArray = [];
$youtubeInfo = json_decode($dur); // let's stick with objects
foreach ($youtubeInfo->items as $video) {
    $videoId = $video->snippet->resourceId->videoId;
    $videoArray[$videoId] = [
        "videoID"   => $videoId,
        "thumbnail" => $video->snippet->thumbnails->medium->url,
        // etc
    ];
}
if(isset($youtubeInfo->nextPageToken)){
    $videoArray = array_merge($videoArray, callone($playlistId, $youtubeInfo->nextPageToken));
}
return $videoArray;

And where you first call callone()

$videos = callone("whatever");
// just store the values
file_put_contents("youtube.json", json_encode(array_values($videos)));

Now your JavaScript can easily parse the flat array of video objects.

function getResults() {
  $.getJSON('/youtube.json', function(data) {
    console.log(data);
    var count = data.length;
    console.log(count);
    data.foreach((video, i) => {
      console.log(video)
    })
  });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the detailed response and helping to optimize the code(as well as the question)! Greatly appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.