PHP: Displaying and updating RSS Content using Ajax
In this article we're going to combine the functionality of our RSS and Atom Feed Reader classes with our JavaScript AjaxRequest class to create a rotating headlines feature.
BBC News
Hogmanay celebrations cancelled as UK-wide weather warnings take hold
High winds, rain and snowfall are expected to bring disruption to parts of the UK from New Year's Eve.
31 December 2024, 3:25am
© {Copyright: (C) British Broadcasting Corporation, see www.bbc.co.uk/usingthebbc/terms-of-use/#15metadataandrssfeeds for terms and conditions of reuse.}
The steps are going to be as follows:
- Download and cache the RSS feed;
- Present the first news item with the feed header and footer;
- Use Ajax to load and display subsequent news items using the cached file.
Can can see an example of this script in operation to the right. A new headline from the RSS feed will be displayed every 5 seconds.
Downloading and caching the RSS feed
We've already presented very similar code to this in a previous article.
The changes in this case are that we will only be displaying the first item from the feed using PHP as the page is loaded. Subsequent feed items will then be loaded using Ajax to replace this initial item. In order to do that we also assign an id (rss_display) to the appropriate section of the HTML as you can see in the code below.
This gives us a target that we can pass to the Ajax function so it knows where the replacement content is to be inserted each time we want the HTML to be updated.
The following PHP code can just be inserted or included into your page:
<?PHP
// define script parameters
$BLOGURL = "https://feeds.bbci.co.uk/news/rss.xml?edition=int";
$TIMEFORMAT = "j F Y, g:ia";
$CACHEFILE = "/tmp/" . md5($BLOGURL);
$CACHETIME = 4; // hours
// download the feed iff a cached version is missing or too old
if(!file_exists($CACHEFILE) || ((time() - filemtime($CACHEFILE)) > 3600 * $CACHETIME)) {
if($feed_contents = file_get_contents($BLOGURL)) {
// write feed contents to cache file
$fp = fopen($CACHEFILE, 'w');
fwrite($fp, $feed_contents);
fclose($fp);
}
}
include "rssparser.php";
$rss_parser = new \Chirp\RSSParser($CACHEFILE);
// read feed data from cache file
$feeddata = $rss_parser->getRawOutput();
extract($feeddata['RSS']['CHANNEL'][0], EXTR_PREFIX_ALL, 'rss');
// display leading image
if($rss_IMAGE) {
extract($rss_IMAGE[0], EXTR_PREFIX_ALL, 'img');
echo "<p><a title=\"{$img_TITLE}\" href=\"{$img_LINK}\"><img src=\"{$img_URL}\" alt=\"\"></a></p>\n";
}
// display feed title
echo "<h4><a title=\"",htmlspecialchars($rss_DESCRIPTION),"\" href=\"{$rss_LINK}\" target=\"_blank\">";
echo htmlspecialchars($rss_TITLE);
echo "</a></h4>\n";
// display first feed item
$itemdata = $rss_ITEM[0];
echo "<p id=\"rss_display\"><b><a href=\"{$itemdata['LINK']}\" target=\"_blank\">";
echo htmlspecialchars(stripslashes($itemdata['TITLE']));
echo "</a></b><br>\n";
echo htmlspecialchars(stripslashes($itemdata['DESCRIPTION'])),"<br>\n";
echo "<i>",date($TIMEFORMAT, strtotime($itemdata['PUBDATE'])),"</i></p>\n\n";
// display copyright information
echo "<p><small>© {",htmlspecialchars($rss_COPYRIGHT),"}</small></p>\n";
?>
With this code we've already completed steps one and two. You can see at the top of the page that the feed logo, heading, a single news item and the footer are displayed as HTML.
Now all we have to worry about is fetching the subsequent news items using Ajax.
Fetching and displaying HTML content using Ajax
To work with Ajax we first need a PHP script that will return the information we need - in this case the DESCRIPTION, LINK, TITLE AND PUBDATE for the selected feed item.
<?PHP
namespace Chirp;
// define script parameters
$BLOGURL = "https://feeds.bbci.co.uk/news/rss.xml?edition=int";
$TIMEFORMAT = "j F Y, g:ia";
$CACHEFILE = "/tmp/" . md5($BLOGURL);
include "Chirp/rssparser.php";
$rss_parser = new RSSParser($CACHEFILE);
// read feed data from cache file
$feeddata = $rss_parser->getRawOutput();
extract($feeddata['RSS']['CHANNEL'][0], EXTR_PREFIX_ALL, 'rss');
$index = isset($_GET['index']) ? $_GET['index'] : 0;
if(count($rss_ITEM)) {
$index = (count($rss_ITEM) + $index) % count($rss_ITEM);
} else {
$index = 0;
}
$itemdata = $rss_ITEM[$index];
// generate the HTML to be returned
$retval = "<b><a href=\"{$itemdata['LINK']}\" target=\"_blank\">";
$retval .= htmlspecialchars(stripslashes($itemdata['TITLE']));
$retval .= "</a></b><br>\n";
$retval .= htmlspecialchars(stripslashes($itemdata['DESCRIPTION'])) . "<br>\n";
$retval .= "<i>" . date($TIMEFORMAT, strtotime($itemdata['PUBDATE'])) . "</i>";
// create an XML file to be returned
include "Chirp/ajaxresponsexml.php";
$xml = new AjaxResponseXML();
$xml->start();
if($retval) {
$xml->command('setcontent', [
'target' => 'rss_display',
'content' => $retval
]);
}
$xml->end();
exit;
The above code, saved as update-rss.xml.php will accept a single $_GET parameter, index, and return the HTML content for displaying that item from the RSS feed. The XML returned contains the instruction to update the element rss_display with the content of the selected item.
This does assume that $CACHEFILE already exists, but that really has to be the case as it's created/updated when the first item is displayed on the page.
Setting the script in motion using JavaScript
The final touch to get the ball rolling is to include some JavaScript that will make the Ajax request and process the instructions returned in XML format by our PHP script:
<script src="/scripts/AjaxRequestXML.js"></script>
<script>
var rss_index = 1;
var rss_delay = 5000;
var updateRSS = function() {
if(encodeURIComponent) {
var params = {
index: rss_index,
};
(new AjaxRequestXML()).get("/scripts/update-rss.xml", params);
rss_index++;
setTimeout(updateRSS, rss_delay);
}
};
setTimeout(updateRSS, rss_delay);
</script>
Again, we're not using anything that hasn't already been presented in previous articles. The only addition here is that we're using the JavaScript setTimeout function to call the script every 5 seconds with the index value being incremented with each call.
If you return to the top of the article you will see that the headlines are updating every 5 seconds. Our script is set to stop after just 20 updates so you may need to refresh the page to set it going again.
XML returned by update-rss.xml.php
Just to show you what's happening behind the scenes, here is the actual XML file returned by an Ajax request for update-rss.xml.php?index=2 - so fetching the third item from the RSS feed:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response><command method="setcontent"><target>rss_display</target><content><![CDATA[<b><a href="https://www.bbc.com/news/articles/c938x3v148yo" target="_blank">Russia and Ukraine exchange hundreds of prisoners of war</a></b><br>
Moscow said 150 Russians were released while Zelensky said 189 Ukrainians had returned home.<br>
<i>31 December 2024, 3:27am</i>]]></content></command></response>
Our AjaxRequestXML class interprets this as a command to update the innerHTML of the element with an id of rss_display with the CDATA-encapsulated HTML content. Simple.
Related Articles - Feed Readers
- PHP RSS Feed Reader Code Example
- PHP Combined RSS and Atom Feed Reader
- PHP Feed Reader with Ajax Updating
- PHP RSS Feed Reader: Source Code
- PHP Displaying and updating RSS Content using Ajax
- PHP RSS and Atom Feed Reader
- PHP YouTube API Feed Reader: Source Code
- PHP Atom Feed Reader: Source Code
Ric Kolseth 18 December, 2009
Great tutorial: Tried it, got it running, but I'm seeing a lot of ERROR NOTICE's: such as:
Undefined index: CHANNEL in ----clip---_rss/class.myrssparser.php on line 58,
Undefined variable: RSS in ----clip---_rss/class.myrssparser.php on line 86,
Undefined index: RSS in ----clip---_rss/class.myrssparser.php(96) : eval()'d code on line 1,
Undefined variable: RSS in ----clip---_rss/class.myrssparser.php on line 86,
Undefined index: LINK in ----clip---_rss/class.myrssparser.php(96) : eval()'d code on line 1,
Undefined variable: RSS in ----clip---_rss/class.myrssparser.php on line 86,
Undefined index: DESCRIPTION in ----clip---_rss/class.myrssparser.php(96) : eval()'d code on line 1,
Undefined index: IMAGE in ----clip---_rss/class.myrssparser.php on line 58,
any idea how I can silence these? I like my scripts to run quiet...
This is a common issue. See the comments here