Easy RSS Feeds in PHP with Simple Pie
Recently, I had to put some RSS feeds on a customer's website but he wanted me to combine 8 different feeds and only grab the most recent ones out of the multiple combined lists. In the past, I've used Magpie RSS to handle RSS feeds. However, Magpie is not really built to handle multiple feeds together. It handles one feed well, though.
Instead, I found SimplePie which makes it easy to handle multiple RSS feeds combined together.
Getting Started
SimplePie has been around for a few years but to be honest it is not as well known as other tools. But, it's a great way to get started easily with putting RSS feeds on your website with less than 10 lines of code.
First, you need to download the SimplePie library. Unzip the file and copy simplepie.inc
somewhere accessible to your web site. For this example, we'll put it in a directory called /inc
just inside your site's DocumentRoot. I rename mine to simplepie.php
for consistency with other libraries I use, but that's not necessary. Here we'll stick with the default .inc
extension.
In this article, I will show how to do four things commonly done with RSS feeds on the web.
- Show the five latest headlines
- Displaying the full content of the single latest post
- How to display two feeds on a single page
- Combining headlines from two feeds into a single list
A note about caching
SimplePie provides a great caching mechanism so that feeds don't have to be retrieved on every page load. This requires a writable directory on the server where the feeds can be stored. By default this location is ./cache
, meaning a directory called 'cache' in the same directory as simplepie.inc
. So for this example, that would be /inc/cache
in your DocumentRoot. For non-shared hosting it's easier to use /tmp
. But in any case, just be sure your web server can write to this directory, either by changing the permissions, ownership, or some other means, as appropriate for your setup.
The default cache time is one hour. Both this and the cache location are customizable but we'll be sticking with the defaults here. See the SimplePie API reference for details when you're ready to dig into this.
Getting started
So here we go. First, load SimplePie by adding this line to the top of the PHP page you'll be using it on:
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/simplepie.inc'; ?>
Once it's loaded, we'll add a second line to create our SimplePie object and give it the location of the RSS or Atom feed we'd like to display:
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/simplepie.inc'; $feed = new SimplePie('http://feeds.corvidworks.com/CorvidWorks'); ?>
That's all the prep work we need. Unless otherwise noted, you'll use this code for all the examples below.
We now have the feed loaded and we can start playing with the contents.
Example One - Display five latest headlines
For this first example we're simply going to display five recent headlines. A typical use case for this might be a someone who wants to automatically link to their latest blog content on another site or on a non-Wordpress page on the same site.
Once the above code is in place, we can start printing out the contents of the feed. First, we'll probably want to display the title of the feed itself. For a Wordpress-based site, this is the same as the blog name.
<h1><?php print $feed->get_title(); ?></h1>
Now let's get the contents. To do this, we'll retrieve an array of posts from the SimplePie object and iterate through them.
<h1><?php print $feed->get_title(); ?></h1> <ul> <?php foreach ($feed->get_items(0, 5) as $item): ?> <li> <a href="<?php print $item->get_permalink(); ?>"> <?php print $item->get_title(); ?></a> </li> <?php endforeach; ?> </ul>
(I broke the list item up into multiple lines so it's easier to read.)
In the above code, you can see our call to SimplePie's get_items()
method. Call this method without the optional arguments will retrieve the entire feed, or pass arguments to get exactly what you want. The first argument specifies the element to start with. Remember, arrays begin with zero so use 0 here to start with the latest post. The second argument is the number of items you want - we're using 5 for this example; use 10 if you want a longer list, 1 if you want a single item, or whatever is appropriate for your needs.
That's it! You've now got a list of headlines, linked to the articles on the original site.
Example Two - Display the latest post content
Displaying the latest full post is pretty similar to the above but we'll be introducing a couple new methods to retrieve a single post and display the post body ('description', in RSS terminology).
<h1>Latest post from <?php print $feed->get_title(); ?></h1> <?php $item = $feed->get_item() ?> <h2><?php print $item->get_title(); ?></h2> <?php print $item->get_description(); ?>
The interesting thing here is that we're calling get_item()
rather than get_items()
(singular instead of plural). By default, this method will return the first item in the feed, which is your most recent post. Add an optional argument of a single integer to specify a different post.
The remaining code is basically the same. We're using the same method to display the title but have added a call to get_description()
for the post body.
Example Three - Show headlines from two feeds
A common use case for SimplePie is to display headlines from a number of sources. Say you've got a person web site that you want to show headlines from the various blogs you write for. Building on what we've done so far, this is no problem at all. Let's see how.
Back up near the beginning of this article, I showed how to include the SimplePie object and instantiate an object for the feed you wish to display. We're going to make a small change to that code here and also create a second SimplePie object for the new feed we'll be adding.
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/simplepie.inc'; $feed1 = new SimplePie('http://feeds.corvidworks.com/CorvidWorks'); $feed2 = new SimplePie('http://feeds.corvidworks.com/Cocktailia'); ?>
So now we've got $feed1
and $feed2
, two SimplePie objects for our two feeds. From here you just follow the five latest headlines instructions above, but using that block twice on your page, using the two different feed variables we've created here.
<!-- First feed - note use of "feed1" --> <h1><?php print $feed1->get_title(); ?></h1> <ul> <?php foreach ($feed1->get_items(0, 5) as $item): ?> <li> <a href="<?php print $item->get_permalink(); ?>"> <?php print $item->get_title(); ?></a> </li> <?php endforeach; ?> </ul> <!-- Second feed - note use of "feed2" --> <h1><?php print $feed2->get_title(); ?></h1> <ul> <?php foreach ($feed2->get_items(0, 5) as $item): ?> <li> <a href="<?php print $item->get_permalink(); ?>"> <?php print $item->get_title(); ?></a> </li> <?php endforeach; ?> </ul>
Example Four - Combine headlines from multiple feeds
For our final example, we're going to combine headlines from two feeds into a single list. You might do this if you've got multiple feeds on a similar topic (entirely unlike the feeds I'm using in this example). Once again, we'll be changing how we instantiate our SimplePie object, this time passing an array of URLs instead of a single one.
<?php include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/simplepie.inc'; $feeds = new SimplePie(array( 'http://feeds.corvidworks.com/CorvidWorks', 'http://feeds.corvidworks.com/Cocktailia' )); ?>
This results in a single object containing data from two feeds, instead of one object for each individual feed. Now we can display them as usual.
<ul> <?php foreach ($feeds->get_items(0, 10) as $item): ?> <li> <a href="<?php print $item->get_permalink(); ?>"> <?php print $item->get_title(); ?></a> </li> <?php endforeach; ?> </ul>
You won't use get_title()
here, as there is no one single title for multiple feeds. You also may want to increase the number of headlines you're showing so you get a good sample from each feed. Note that these are displayed in date order so you may have an uneven number of posts from each (real world usage of this example gives me three headlines from this site and seven from Cocktailia).