A simple RSS Reader with PHP

Aggregate feeds from mutiple sources, with UTF-8 support and relative dates

In the last couple of days, I had the need of creating a simple RSS widget for a project, aggregating several RSS feeds from different sources. As this might be a pretty common request and you might need this in your projects, I’m sharing my script below.
The whole thing is based on the MagpieRSS PHP parser.

1. The simple version

This first version simply reads the RSS feeds from different websites and lists the latest posts for each website.
Feed URIs are defined in an array, so you can easily add as many as you want.
Number of posts per website is also easily editable.

This has support for languages different from English, using UTF-8 encoding, and uses relative dates.

You can see a working example here.

Source code:


<?php

/* feed URIs */
$urls = array('http://webdesignerwall.com/feed/', 'http://gigaom.com/feed/', 'http://techcrunch.com/feed/', 'http://wordpress.org/development/feed/');

/* number of items for each feed */
$num_items = 5;

@require_once('rss_fetch.inc');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
$posts = array();

foreach($urls as $url) {
$rss = fetch_rss($url);

if($rss) {
$items = array_slice($rss->items, 0, $num_items);
foreach($items as $item) {
$posts[] = array('title' => $item['title'], 'link' => $item['link'], 'date' => $item['pubdate'], 'source' => $rss->channel['title']);
}
}
else {
echo "An error occured!<br />Error Message: ".magpie_error();
}
}
usort($posts, 'sortdates');
echo "<ul>";
foreach($posts as $post) {
$title = $post['title'];
$url = $post['link'];
$date = $post['date'];
$source = $post['source'];
echo "<li><a href='".$url."'>".$title."</a> from <strong>".$source."</strong>, ".getrelativetime($date)."</li>";
}
echo "</ul>";

function sortdates($a, $b) {
if(strtotime($a['date']) > strtotime($b['date'])) {
return -1;
} elseif( strtotime($a['date']) == strtotime($b['date'])) {
return 0;
} elseif( strtotime($a['date']) < strtotime($b['date'])) {
return 1;
}
}

function getrelativetime($date) {
// Credit: http://snipplr.com/view/4912/relative-time/ and http://twitter.pbwiki.com/RelativeTimeScripts
$gap = time() - strtotime($date);
if ($gap<5) {
return 'less than 5 seconds ago';
} else if ($gap<10) {
return 'less than 10 seconds ago';
} else if ($gap<20) {
return 'less than 20 seconds ago';
} else if ($gap<40) {
return 'half a minute ago';
} else if ($gap<60) {
return 'less than a minute ago';
}
$gap = round($gap/60);
if ($gap < 60)
return $gap.' minute'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/60);
if ($gap < 24)
return $gap.' hour'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/24);
if ($gap<7)
return $gap.' day'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/7);
if ($gap<4)
return $gap.' week'.($gap > 1 ? 's' : '').' ago';

return date("F jS, Y @h:i", strtotime($date));
}
?>

2. The more complex version

Same thing as above, but this version output a list af the most recent posts – source websites are displayed next to titles. This is definitely more useful if you mean to display recent content from mixed sources.

You can see a working example here.

Source code:


<?php

/* feed URIs */
$urls = array('http://webdesignerwall.com/feed/', 'http://gigaom.com/feed/', 'http://techcrunch.com/feed/', 'http://wordpress.org/development/feed/');

/* number of items for each feed */
$num_items = 5;

@require_once('rss_fetch.inc');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
$posts = array();

foreach($urls as $url) {
$rss = fetch_rss($url);

if($rss) {
$items = array_slice($rss->items, 0, $num_items);
foreach($items as $item) {
$posts[] = array('title' => $item['title'], 'link' => $item['link'], 'date' => $item['pubdate'], 'source' => $rss->channel['title']);
}
}
else {
echo "An error occured!<br />Error Message: ".magpie_error();
}
}
usort($posts, 'sortdates');
echo "<ul>";
foreach($posts as $post) {
$title = $post['title'];
$url = $post['link'];
$date = $post['date'];
$source = $post['source'];
echo "<li><a href='".$url."'>".$title."</a> from <strong>".$source."</strong>, ".getrelativetime($date)."</li>";
}
echo "</ul>";

function sortdates($a, $b) {
if(strtotime($a['date']) > strtotime($b['date'])) {
return -1;
} elseif( strtotime($a['date']) == strtotime($b['date'])) {
return 0;
} elseif( strtotime($a['date']) < strtotime($b['date'])) {
return 1;
}
}

function getrelativetime($date) {
// Credit: http://snipplr.com/view/4912/relative-time/ and http://twitter.pbwiki.com/RelativeTimeScripts
$gap = time() - strtotime($date);
if ($gap<5) {
return 'less than 5 seconds ago';
} else if ($gap<10) {
return 'less than 10 seconds ago';
} else if ($gap<20) {
return 'less than 20 seconds ago';
} else if ($gap<40) {
return 'half a minute ago';
} else if ($gap<60) {
return 'less than a minute ago';
}
$gap = round($gap/60);
if ($gap < 60)
return $gap.' minute'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/60);
if ($gap < 24)
return $gap.' hour'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/24);
if ($gap<7)
return $gap.' day'.($gap > 1 ? 's' : '').' ago';
$gap = round($gap/7);
if ($gap<4)
return $gap.' week'.($gap > 1 ? 's' : '').' ago';

return date("F jS, Y @h:i", strtotime($date));
}
?>

Download the source code for both scripts (24k ZIP)

This tutorial is provided as is. Please do not email me questions or support requests about the scripts contained in this page. Use the comments below instead. Thank you.


About this entry