skip to content

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

Vennells told she is in 'la-la land', as Post Office convictions to be overturned
A law quashing sub-postmasters' convictions from the Horizon IT scandal comes into force later today.
24 May 2024, 6:29pm

« prev | pause | next »

The steps are going to be as follows:

  1. Download and cache the RSS feed;
  2. Present the first news item with the feed header and footer;
  3. 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 = ""; $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>&copy; {",htmlspecialchars($rss_COPYRIGHT),"}</small></p>\n"; ?>

expand code box

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    "";   $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($TIMEFORMATstrtotime($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="" target="_blank">Watch as BBC reaches a hidden war’s jungle front line</a></b><br> The BBC spends a month inside Myanmar, where young medics, teachers and fighters are powering the revolution against the ruling military junta. <br> <i>24 May 2024, 7:01am</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.


User Comments

Post your comment or question

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