I am trying to make a website that displays the most recent result for a specific YouTube search. Using PHP I can successfully call the API and grab the video ID I need, but I am having trouble using this to update the user-facing HTML page. I want the PHP script to update the HTML file itself, so the user loads the page with the most recent result already embedded (or the most recent result since the script has last ran, which I intend to schedule every 15 minutes or so).
Here is the HTML (main.html
), I am trying to replace src
link in the iframe. It should go from this:
<div id="videoembed">
<iframe width="697" height="392" src="https://www.youtube.com/embed/CZIINXhGDcs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
To this:
<div id="videoembed">
<iframe width="697" height="392" src="https://www.youtube.com/embed/ElGoC3qFYRg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
I'm not concerned about the values other than src
at this time
Following the answers to this question I have tried replacing the element through its nodeValue, but the result is that I get a test.html
file with the same iframe as the original, so a file was created but without the replacement executed. (I am saving to test.html
for testing purposes, the final version will simply overwrite the main.html
):
///Turn the API response into a usable json
$response = json_encode($service->search->listSearch('snippet', $queryParams));
///get the videoId
preg_match('/(?<=videoId"\:")(.*)(?="})/', $response, $output_array);
///use the videoId to make an iframe called $output_embed
$embed1 = "<iframe width=\"697\" height=\"392\" src=\"https://www.youtube.com/embed/";
$embed2 = "\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>";
$output_embed = $embed1 . $output_array[0] . $embed2;
///create a document
$doc = new DOMDocument();
///load in the main page with the existing embedded video
$html = "main.html";
$doc->loadHTMLFile($html);
///grab the contents of the videoembed div and replace them with the contents of the $output_embed
$belement = $doc->getElementById('videoembed');
$oldString = $belement->nodeValue;
$newHTML = str_replace($oldString,$output_embed,$html);
$doc->saveHTMLFile("test.html");
I tried preg_replacing it too like this answer, but I got the same result of a new test.html
file with no changes.
$doc = new DOMDocument();
$html = "main.html";
$doc->loadHTMLFile($html);
$html = preg_replace('/<iframe.*?<\/iframe>/', $output_embed, $html);
$doc->saveHTMLFile("test.html");
I think I am missing something fundamental here. I feel like my code just is not interacting with what I need it to. Whenever I try to print out the nodevalue or any way of grabbing the contents of the I get a blank result. Not very familiar with PHP (no formal coding training in general), I think I may be misunderstanding something with strings or arrays or ways that certain variables are handled.
Here is my current workaround (which is slow because the user has to get current.html
):
PHP:
///Turn the API response into a usable json
$response = json_encode($service->search->listSearch('snippet', $queryParams));
///get the videoId
preg_match('/(?<=videoId"\:")(.*)(?="})/', $response, $output_array);
///create a document
$doc = new DOMDocument();
///force a full iframe into it in 3 parts: before the videoId, videoId, and after the videoId
$doc->loadHTML("<iframe width=\"697\" height=\"392\" src=\"https://www.youtube.com/embed/" . $output_array[0] . "\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>");
$doc->saveHTMLfile("current.html");
HTML:
<div id="videoembed">
<?php
include 'current.html';
?>
</div>
It works fine, but it feels a lot slower than it could be.