skip to content

PHP: Feed Reader with Ajax Updating

This is a rewrite of a previous article which demonstrated the same RSS/Ajax functionality using our ald RSSParser PHP class. This version takes advantage of our new, more efficient and flexible, FeedParser class.

Working Demonstration

To the right you should see a news headline displayed in a floated container. And every few seconds the page will make an Ajax call to fetch and display the next headline.

The RSS feed contents are cached on the first request so our Ajax script can source them from the same file instead of making a new HTTP request each time.

The fetching of new headlines is triggered using a simple setTimeout call that is repeated a set number of times.setInterval to have an infinite rotation of headlines.

The advantage of Ajax is that we are only loading the first headline into the HTML content. Loading all the news items on page load into a slideshow would be easier, but would bloat the page affecting speed and SEO.

PHP Source Code

The code that we have added to the page itself is shown below. It will load the first (most recent) item from the RSS feed into the page.

<aside class="rss-display"> <?PHP $BLOGURL = "insert your rss or atom feed url here"; $TIMEFORMAT = "j F Y, g:ia"; $CACHEFILE = "/tmp/" . md5($BLOGURL) . ".xml"; $CACHETIME = 4; /* hours */ if(!file_exists($CACHEFILE) || ((time() - filemtime($CACHEFILE)) > 3600 * $CACHETIME)) { if($feed_contents = http_get_contents($BLOGURL)) { file_put_contents($CACHEFILE, $feed_contents); } } try { $parser = new \Chirp\FeedParser($CACHEFILE); $channel = $parser->get_channel(); $item = $parser->get_items(1)[0]; /* display channel header */ if(isset($channel['image']) && $channel['image']) { echo "<p><a"; echo " title=\"",htmlspecialchars($channel['image']['title']),"\""; echo " href=\"",htmlspecialchars($channel['image']['link']),"\">"; echo "<img src=\"",htmlspecialchars($channel['image']['url']),"\" alt=\"\">"; echo "</a></p>\n"; } echo "<h4><a title=\"",htmlspecialchars($channel['description']),"\" href=\"{$channel['link']}\" target=\"_blank\">"; echo htmlspecialchars($channel['title']); echo "</a></h4>\n"; /* display first headline */ echo "<p id=\"rss_display\" class=\"rss-body\">"; echo "<a href=\"",htmlspecialchars($item['link']),"\" target=\"_blank\">"; echo htmlspecialchars(stripslashes($item['title'])); echo "</a><br>\n"; echo htmlspecialchars(stripslashes($item['description'])),"<br>\n"; echo "<span class=\"rss-date\">",date($TIMEFORMAT, strtotime($item['pubDate'])),"</span>"; echo "</p>\n\n"; /* display channel footer */ echo "<p class=\"rss-copyright\">&copy; {<?= htmlspecialchars($channel['copyright']); ?>}</p>\n" } catch(\Exception $e) { echo "<p>XML parse error: " . $e->getMessage(),"</p>\n"; } ?> </aside> <!-- .rss-display -->

At this stage the display is static and won't update. You can use this approach to embed any number of feeds and items into your website if you want without worrying about the Ajax component.

JavaScript Source Code

The following JavaScript will make an Ajax request every five seconds with an incrementing value for index which is passed as a GET parameter:

<script> const updateFeed = function() { var params = { index: rssIndex, }; (new AjaxRequestXML()).get("feed-reader-ajax.xml.php", params); rssTimer = setTimeout(updateFeed, rssDelay); rssIndex++; }; let rssIndex = 1; let rssDelay = 5000; let rssTimer = setTimeout(updateFeed, rssDelay); </script>

The script can be halted using clearTimeout(rssTimer) and will otherwise run indefinitely.

In practice you will want to determine the number of available items in the feed at the start and use that to create a loop that returns to the beginning once all the headlines have been displayed. The code as presented neither loops nor stops.

Ajax (PHP) Source Code

The final piece of the puzzle is the feed-reader-ajax.xml.php Ajax script, most of which you will recognise from the PHP source code above, only this time instead of displaying the HTML we're returning it to the requesting page:

<?PHP if(!isset($index) || !is_numeric($index)) { die("Missing or invalid index parameter."); } $BLOGURL = "insert your rss or atom feed url here"; $TIMEFORMAT = "j F Y, g:ia"; $CACHEFILE = "/tmp/" . md5($BLOGURL) . ".xml"; $retval = NULL; try { $parser = new \Chirp\FeedParser($CACHEFILE); if($items = $parser->get_items(1, $index)) { $item = current($items); ob_start(); echo "<a href=\"",htmlspecialchars($item['link']),"\" target=\"_blank\">"; echo htmlspecialchars(stripslashes($item['title'])); echo "</a><br>\n"; echo htmlspecialchars(stripslashes($item['description'])),"<br>\n"; echo "<span class=\"rss-date\">",date($TIMEFORMAT, strtotime($item['pubDate'])),"</span>"; $retval = ob_get_clean(); } } catch(\Exception $e) { $retval = "XML parse error: " . $e->getMessage(); } // generate XML to be returned $xml = new \Chirp\AjaxResponseXML(); $xml->start(); if($retval) { $xml->command('setcontent', [ 'target' => "rss_display", 'content' => $retval ]); } $xml->end(); exit;

The script loads the 'index'th item from the cached XML feed and returns it to be inserted into the page at #rss_display updating the headline section of our display.

We do not need to load/display the channel details as they are already on the page. All the Ajax script needs to return is the HTML markup of the requested news item.

< PHP

Post your comment or question
top