Build Your Own RSS Feed Reader (Posted on March 23rd, 2013)

It's not everyday that a company with a significant market share in a sector gives up that market share. The RSS industry has seen a significant landscape change recently with Google's announcement to power down Reader. Quite a few new feed readers have sprung up recently and several existing ones have been rapidly iterating their software to handle the new influx of users. I'm personally content with using Hacker News and Reddit as my feed readers but I understand people's desire for a more customized experience.

For those that enjoy their feed readers I'm here to offer a solution that you can personalize to no end and will never go away. This post is going to go over building a feed reader in PHP and showing just how simple it can be to aggregate your news to one place where you have full control.

Building Our Feed

The process as you can imagine is pretty simple. Take a list of feeds, get the stories from each feed, sort the combination of stories by date published, then output the results. Let's start by defining our list of feeds.

<?php 
//Feed URLs
$feeds = array(
    "http://maxburstein.com/rss",
    "http://www.engadget.com/rss.xml",
    "http://www.reddit.com/r/programming/.rss",
);
?>

PHP5 comes with a great XML parser called SimpleXML. Let's go ahead and load the feed data into our parser.

//Read each feed's items
$entries = array();
foreach($feeds as $feed) {
    $xml = simplexml_load_file($feed);
    $entries = array_merge($entries, $xml->xpath("//item"));
}

The xpath method on our XML object is basically a string parser. Starting from the root of our XML data it goes down two children and get's all of the children enclosed in an item tag.

Here are the basics of how an RSS feed is structured so you can see why we need to go two children deep to access the item entries.

<rss>
    <channel>
        <title>Feed title</title>
        <link>Link where feed data is pulled from</link>
        <description>Description of feed</description>
        <item>Entry from a feed</item>
        <item>Entry from a feed</item>
        <item>Entry from a feed</item>
        <item>Entry from a feed</item>
        <item>Entry from a feed</item>
    </channel>
</rss>

Now that we have all the entries stored in an array we need to sort them. Otherwise the feeds will show up in the order we have them listed in our feeds array. All my items would be listed first, followed by all the Engadget items, followed by all the Reddit Programming items. All the items should have a pubDate tag that we can sort by. Since we've read all the feed data in as a string we have to remember to convert it to an integer for easy comparison which "strtotime" will take care of for us.

//Sort feed entries by pubDate
usort($entries, function ($feed1, $feed2) {
    return strtotime($feed2->pubDate) - strtotime($feed1->pubDate);
});

Our final step is just to output our entries. Each item will usually have at least the following attributes: title, link, and description. So let's use these to build our output.

<ul><?php
//Print all the entries
foreach($entries as $entry){
    ?>
    <li><a href="<?= $entry->link ?>"><?= $entry->title ?></a> (<?= parse_url($entry->link)['host'] ?>)
    <p><?= strftime('%m/%d/%Y %I:%M %p', strtotime($entry->pubDate)) ?></p>
    <p><?= $entry->description ?></p></li>
    <?php
}
?>
</ul>

RSS Feed Reader

That's all that's needed. You can add some CSS styling in if you want to mirror the effect of other feed readers. If you want to play around with the final source code you can fork it from this Github gist or check it out below.

Final Source Code

<html>
    <head>
        <title>RSS Feed Reader</title>
    </head>
    <body>
        <?php
        //Feed URLs
        $feeds = array(
            "http://maxburstein.com/rss",
            "http://www.engadget.com/rss.xml",
            "http://www.reddit.com/r/programming/.rss"
        );
        
        //Read each feed's items
        $entries = array();
        foreach($feeds as $feed) {
            $xml = simplexml_load_file($feed);
            $entries = array_merge($entries, $xml->xpath("//item"));
        }
        
        //Sort feed entries by pubDate
        usort($entries, function ($feed1, $feed2) {
            return strtotime($feed2->pubDate) - strtotime($feed1->pubDate);
        });
        
        ?>
        
        <ul><?php
        //Print all the entries
        foreach($entries as $entry){
            ?>
            <li><a href="<?= $entry->link ?>"><?= $entry->title ?></a> (<?= parse_url($entry->link)['host'] ?>)
            <p><?= strftime('%m/%d/%Y %I:%M %p', strtotime($entry->pubDate)) ?></p>
            <p><?= $entry->description ?></p></li>
            <?php
        }
        ?>
        </ul>
    </body>
</html>

As always if you have any feedback or questions feel free to drop them in the comments below or contact me privately on my contact page. Thanks for reading!

Tags: PHP

Comments:

  • Anonymous - 1 year, 4 months ago

    Hi, I tried your reader, but when it loaded, it displayed some weird results. They go along the lines of this (best approximation) * title ?>(link)['host']?>) pubDate))?> description ?> I'm not sure where my error is. Any help would be appreciated.

    reply

  • Max Burstein - 1 year, 4 months ago

    The syntax highlighter uses escaped html characters to display properly. So if you copy and pasted from there it may cause the issue. Try grabbing it off the Github Gist. If that's not the issue then it is possible that the RSS feed(s) you're pulling from are formatted in a weird way. Another issue may be that you have short tags disabled in PHP. Short tags allow rather than having to type out

    reply

  • Paris - 1 year, 4 months ago

    Excellent read, I just passed this onto a colleague who was doing a little study on that. And he really bought me lunch because I discovered it for him smile So let me rephrase that: Thanks for lunch!

    reply

  • Anonymous - 4 months, 2 weeks ago

    I'm getting this error when I try to run this reader.

    Parse error: syntax error, unexpected '[', expecting ',' or ';' in /home/thegreen/www/www/school/CnJ/rss_reader.php on line 32

    I assume its an issue with (<?= parse_url($entry->link)['host'] ?>) but I have no idea why and when my friend runs the same code, his works. Any thoughts?

    reply

  • Max Burstein - 4 months, 2 weeks ago

    The feed you're parsing may not have one of the fields you're looking for. If you and your friend are using the same code on the same feed then it would have to be the version of PHP that you're running. What feed are you trying to parse?

    reply

  • Anonymous - 4 months, 1 week ago

    Hi. I was trying to use your code but the text editor is giving error report on line: <li><a href="<?= $entry->link ?>"><?= $entry->title ?></a> (<?= parse_url($entry->link)['host'] ?>)

    I'm a bit new to php so pardon for eventual noob comments. Is the '<?=' really meant to be or was a spelling error?

    Thanks

    reply

  • Max Burstein - 4 months, 1 week ago

    The code looks fine to me. <?= is a shortcut for <? echo. Here is more info about it if you're interested http://programmers.stackexchange.com/questions/151661/is-it-bad-practice-to-use-tag-in-php

    reply

  • St.Petersburg - 4 months ago

    Heya! I just wanted to ask if you ever have any issues with hackers? My last blog (wordpress) was hacked and I ended up losing many months of hard work due to no data backup. Do you have any solutions to protect against hackers?

    reply

  • Max Burstein - 4 months ago

    I have rolling back ups with Heroku as far as data goes. I use Django for this blog so it has a lot of built in security features as does PHP. No system is without flaws I suppose. You just have to learn from your mistakes and move on. With that said moving to a PaaS such as Heroku where server security is more or less handled for you and all you have to take care of is the actual code of your application.

    reply

  • Tony - 2 months, 1 week ago

    With this example could I enter any RSS feed like," http://toledo.craigslist.org/search/ppa?query=furnace&s=0&format=rss" and it will work?

    reply

  • Max Burstein - 2 months ago

    Yea it should be fine. Give it a try.

    reply