Consuming RSS Feeds

How to Read an RSS Feed With PHP - screencast

Oct 22nd in Screencasts by Jeffrey Way

Back in April, Collis Ta'eed - CEO of Envato - wrote a fantastic tutorial on designing a tab structure using CSS/HTML/JS.

If you haven't already, I 100% recommend that you review it. However, dynamically pulling in an RSS feed was beyond the scope of that article. In today's video tutorial, I'll show you exactly how to do this using PHP. At roughly forty-five minutes in length, you might want to take a quick "pre-screencast bathroom break". You also might want to grab some raisins.

Author: Jeffrey Way

Hi, I'm Jeff. I'm the editor of NETTUTS, and the Site Manager of Theme Forest. I spend too much time in front of the computer and find myself telling my fiance', "We'll go in 5 minutes!" far too often. I just can't go out to dinner while I'm still producing FireBug errors...drives me crazy. I love the ASP.NET framework, jQuery, PHP, CSS, AJAX - pretty much anything.

There's a strange issue with converting this video to Flash. At least for the next couple of hours, you can watch the video HERE. I'll embed the video on this site shortly.

Our Goal

We'll be creating a tab system for three unique RSS feeds:

We want to dynamically import these feeds into our document. Our server-side script of choice today will be PHP, and we'll use some jQuery to create the tab structure.

*Note - the intention of this tutorial is to demonstrate the back-end work involved. As mentioned previously, Collis has already created a wonderful skin. Just as the programming was beyond the scope of that tutorial, working on "design" will be beyond the scope of this article. To keep things as clean and "to the point" as possible, we'll be using the most naked form of a tab structure - speaking in terms of the design.

Collis's final product.

Collis

Our naked skin

Tab Final

Step 1: Creating the File Structure

Open your favorite code editor and create the following folders/files. The PHP files can be blank for now.

File Structure

Step 2: The Logic

Open your "functions.php" file. We'll be creating only one function that's relatively simple. First, copy in the following code. After that, continue reading for the code analysis.

<?php

function getFeed($feed_url) {
	
	$content = file_get_contents($feed_url);
	$x = new SimpleXmlElement($content);
	
	echo "<ul>";
	
	foreach($x->channel->item as $entry) {
		echo "<li><a href='$entry->link' title='$entry->title'>" . $entry->title . "</a></li>";
	}
	echo "</ul>";
}
?>

First, we're creating a function called getFeed(). The basic structure of any PHP function is:

function someName($parameters) {
...some method
}

Next, we're creating a variable called "$content" and making it equal to the result of: file_get_contents($feed_url).

"file_get_contents" is the preferred way to read the contents of a file into a string."

Now that you understand the definition, we only need to pass in our file. We have two choices. First, we could pass in a string to our RSS feed - like so:

file_get_contents("http://feedproxy.google.com/nettuts");

That would work just fine, I suppose. The method would correctly read the RSS feed and store the results in our "$content" variable. But, we should always have the word "reusability" lurking in the back of our minds when working.

Imagine that we have many different pages in our web application that want to call this "getFeed()" function. But, what if they want to grab different feeds? Wouldn't it be nice if we could pass the url into the function instead of hard-coding it? Of course it would! Consequently, rather than inputting the path, we'll simply use a variable called "$feed_url".

file_get_contents($feed_url);

In order to use this variable from an outside source, we need to make sure that the function accepts one parameter.

function getFeed($feed_url){

}

Now, when we call the function, we can do so like this:

<?php getFeed("path to some RSS feed"); ?>

Next, we'll create a new instance ($x) of SimpleXmlElement. Within the parenthesis, we'll pass in our $content variable.

$x = new SimpleXmlElement($content);

Finally, we need to run through the RSS feed and extract the information that we desire.

	echo "<ul>";
	
	foreach($x->channel->item as $entry) {
		echo "<li><a href='$entry->link' title='$entry->title'>" . $entry->title . "</a></li>";
	}
	echo "</ul>";

We begin by echoing the opening unordered list tag. Then, we cycle through each entry in our RSS feed using a "foreach" statement. This statement basically says, "create a variable called $entry that will contain the value of each item tag in our RSS feed.

The wonderful thing about RSS feeds is that they all implement the same basic structure. Every feed contains a wrapping "channel" tag. Then, each posting in your feed will be wrapped within an "item" tag. All of the information that we need can be accessed this way.

RSS Info

Within our "foreach" statement, we only need to extract the link and title, and place it within an "li" tag. The "link" tag contains a link to the actual posting. The title tag obviously houses the title of the posting. That's all that we'll need for this particular project, but I'd advise you to review some of the other information that is available to you. Simply view the source of any RSS feed to analyze the structure.

Our logic is now complete. We now need to create our index.php page and call the function.

Step 3: The Index.php Page

Paste the following code into your index.php page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
	<link rel="stylesheet" href="css/default.css" />
	<script src="js/jquery-1.2.6.pack.js" type="text/javascript"></script>
	<script src="js/myScript.js" type="text/javascript"></script>
</head>
<body>
<?php require_once "includes/functions.php"; ?>
<div id="wrap">

<ul id="nav">
<li><a href="#content_1" class="selected">NETTUTS</a></li>

<li><a href="#content_2">ThemeForest</a></li>
<li><a href="#content_3">Screencasts</a></li>
</ul>

	<div id="mainContent">

		<div id="content_1">
			<?php getFeed("http://feedproxy.google.com/nettuts"); ?>
		</div><!--end content 1-->

		<div id="content_2">
			<?php getFeed("http://feedproxy.google.com/themeforest"); ?>
		</div><!--end content 2-->

		<div id="content_3">
			<?php getFeed("http://feeds.feedburner.com/NETTUTSVideos"); ?>
		</div><!--end content 3-->

	</div><!--end main content -->

</div><!--end wrap-->
</body>
</html>

As I said earlier, I don't want to go too much into the "design". Collis has already done that for you. Refer to that tutorial for your "design fix". But for a speedy overview, we're storing our navigation links within an unordered list that has an id of "nav". In our main content section, we have three divs named "content_1", "content_2", and "content_3", respectively. Inside each division is where we call our "getFeed" function - and pass in the different urls to our RSS feeds.

Add in some extremely basic CSS and you get this:

what we have now

Implementing the Tabs With jQuery

jQuery Website

Open your "myScripts.js" file and paste in the following code:

$(function() {
    $('#mainContent div:not(:first)').hide();

    $('ul li a').click(function() {
        $('ul#nav li a').removeClass('selected');
        $(this).addClass('selected');

        var href = $(this).attr('href');
        var split = href.split('#');

        $('#mainContent div').hide();
        $('#mainContent div#' + split[1]).fadeIn();

        return false;
    });
});

When the document is ready to be manipulated, we'll grab all of our content divs - but not the very first one - and hide them. This will remove the second two RSS feeds.

Next, when a user clicks on one of our navigation links, we'll run a function. Inside this function, we'll remove the class "selected" from all of our navigation anchor tags. This class is used to provide some visual feedback as to which tab is currently selected. In this naked example, I've simply made the text bold for that particular tab. Now we add this class specifically to the anchor tag that was clicked - $(this).addClass('selected');

Moving along, we're creating a variable called 'href' and are making it equal to the href of the anchor tag that was clicked. If we refer back to our document, these navigation tags link to the sections within the main content - "#content_1", "#content_2", "#content_3". The idea is that, if the user doesn't have Javascript enabled, these links will scroll the user directly to the proper feed.

This additionally serves another unique advantage. Consider this: the NETTUTS navigation tag has its url set to "#content_1". Now, in the main content section, the div with an id of "content_1" houses our NETTUTS RSS feed. So...we have made a connection between the two! I hope that makes sense; it's a little hard to describe. Refer to the screencast if I didn't illustrate this point well enough.

I'm going to use "split" to strip off the # sign. Split works in the same way as PHP's explode function does.

var split = href.split('#');

Now, the "split[1]" array will be equal to "content_1". The final step is to find the main content div that has that exact id and fade it in accordingly.

$('#mainContent div#' + split[1]).fadeIn();

I hope this tutorial has helped you. Once you combine the design from Collis's tutorial with the logic from this one, you'll find yourself with a fantastic addition to your sidebar. Though, this tut should serve as the first step for beginners. I welcome all of you to refine the code to make it more advanced and error proof. I didn't go into the latter part in order to save something for Part 2! :p

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Related Posts

Check out some more great tutorials and articles that you might like

Enjoy this Post?

Your vote will help us grow this site and provide even more awesomeness

User Comments

( ADD YOURS )
  1. Tom Cameron October 22nd

    A very nice short tutorial — I already knew the SimpleXMLElement way of parsing RSS feeds but the section on tabbed JQuery is something that I had missed earlier tutorials on. Thanks!

    And, woo, first comment!


  2. Steve October 22nd

    Nice tutorial. First?


  3. Barttos October 22nd

    Wow, cool tutorial!


  4. Julien L October 22nd

    Very good tutorial ! I like the way you describe all of your steps. Very instructive !


  5. Marco October 22nd

    You could also use the “simplexml_load_file” PHP function to parse the XML file (RSS feed).

    Anyway, thanks for this useful tutorial!


  6. Lamin Barrow October 22nd

    Parsing, Consuming and exposing XML is a necessity in modern web development. I am glad you took time write this tut Jeffery. Many Thanks.


  7. Shane October 22nd

    Great stuff. I wrote a similar tutorial (albeit minus jQuery stuff) about formatting Amazon ‘Listmania’ XML using PHP and simplexml_load_string.

    I hope you guys don’t mind the shameless plug: http://www.freshclickmedia.com/blog/2007/11/displaying-amazon-lists-on-your-blog-using-php/

    :p


  8. Chad October 22nd

    I’m stoked about this tut Jeffery but blip.tv keeps crashing firefox…anyone else having this issue?


  9. Jeffrey Way October 22nd

    @Chad - Strange. Must be because it’s an AVI. If you look below the video, there should be an option to switch to the M4V format. This should help.

    For some reason, when I originally exported the movie, it refused to convert to Flash properly. I’m reuploading it, but that can take a couple of hours. As soon as it is finished, I’ll update this posting to include the embedded video.

    JW


  10. Theo October 22nd

    I copied / paste the code, set everything up on my website… and I get an error every time:

    Fatal error: Cannot instantiate non-existent class: simplexmlelement in /home/www/mywebsitename/www/rssparse/includes/functions.php on line 6

    weird

    any advice ?

    PS: This tutorial is really good other than that but i’d love to fix my issue.

    I tried parsing feeds with SimplePie and it works well but it’s a heavier set up than this.


  11. Jeffrey Way October 22nd

    @Theo - Are you using the latest version of PHP?


  12. Theo October 22nd

    i think so, the hoster i have is usually good and running the latest versions. It says: 4.4.8 / 5.2.5 right now.


  13. Jeffrey Way October 22nd

    Can you run it locally to check?

    Using WAMP or MAMP?


  14. Eduardo October 22nd

    simply amazing! I loved it!


  15. Theo October 22nd

    @Jeffrey

    I just tried with another hoster (MediaTemple) and it does the same.

    Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /mywebsitename/html/rssparse_test/includes/functions.php on line 5

    Has anybody else tried to copy/paste the code and files/folders from the demo ?

    Weird hey.

    I dont have MAMP installed on this computer but since the error is the same on both hosters it’s weird.


  16. Thiemo Gillissen October 22nd

    I get the same error:

    “Fatal error: Cannot instantiate non-existent class: simplexmlelement in …/functions.php on line 7″

    Which PHP version is required to run it?

    Thanks,

    Thiemo


  17. Shane October 22nd

    I know that I’ve had problems on Dreamhost with remote file access… possibly with file_get_contents, I can’t remember now.

    I had to use CURL to get the response, and then load the XML response using simplexml_load_string.

    Hope this helps.


  18. Binny V A October 22nd

    How much code must be changed to make it work on atom as well?


  19. Jeffrey Way October 22nd

    Strange. I simply copied the files over to my host and it worked perfectly.

    Do any of you PHP ninjas have any ideas? I primarily am an ASP.NET guy.


  20. Theo October 22nd

    i’m a CSS/XHTML guy so i will definitely not be able to investigate hehe


  21. Shane Porter October 22nd

    @Jeffrey - which host are you using?

    As I said, I have had issues in the past with requesting resources from other servers. The issue is that slowly responding remote servers can have an adverse affect on shared server resources.

    On Dreamhost, I had to use CURL to request the other resource, as other methods weren’t permitted.


  22. insic October 22nd

    it works in my host. this tutorial is great. thanks


  23. Thomas Milburn October 22nd

    This is a brilliant tutorial but I hear some people are having problems getting this to work. Firstly SimpleXML must be installed on your server. It is installed by default but only runs on PHP 5+.

    Secondly, for security reasons file_get _contents may not be able to access a url. The allow_url_fopen parameter must be set to 1 in you php.ini file. Again your web host may not allow you to change this parameter. If this is the case, you can use the curl module to request a file from a remote url.

    I hope that helps solve some issues. If you are using Wordpress you may be interested in using wordpress’s rss feed reader using the function fetch_rss()


  24. Thomas Milburn October 22nd

    @Binny
    To use this with an atom feed, I believe all you need to do is change:
    foreach($x->channel->item as $entry) {
    to
    foreach($x->feed->entry as $entry) {
    I haven’t tried this though so I might be wrong!


  25. Robert October 22nd

    Hi all!

    Nice example!

    About the problems with the file_get_contents() function. Be sure to check in your PHP setting (hint: use phpinfo()), to see is the allow_url_fopen set to On. If not try setting it in the php.ini or try with the ini_set (http://www.php.net/manual/en/function.ini-set.php) function:
    ini_set(’allow_url_fopen’,'On’);
    This may not be working, depends on the hosting. If doesn’t work, then you must use curl if it’s enabled, as someone mentioned.
    Also the simpleXml should be loaded (http://www.php.net/manual/en/simplexml.setup.php)

    Happy hacking :)


  26. Robert October 22nd

    While this tut covers reading RSS feeds by parsing the XML quite well, you can take the ‘pain’ away by using the fantastic SimplePie RSS library: http://simplepie.org/. SimplePie provides great functionality for handling and reading RSS feeds. You can give it a site URL and it can discover the feed on it, you can give it multiple RSS URLs and it will aggregate them for you. It implements disk caching so you can speed up your site’s response. There are many more features of SimplePie… Just check it out :).


  27. Craig October 22nd

    Thanks for the Tutorial. When I load it up the feeds are pulled nicely from nettuts and themeforest but when i plug in a different rss link i get:

    Warning: file_get_contents(http://feeds.feedburner.com/comparesummersales) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/content/c/r/a/craigohobson/html/test.php on line 5

    Fatal error: Uncaught exception ‘Exception’ with message ‘String could not be parsed as XML’ in /home/content/c/r/a/craigohobson/html/test.php:7 Stack trace: #0 /home/content/c/r/a/craigohobson/html/test.php(7): SimpleXMLElement->__construct(”) #1 /home/content/c/r/a/craigohobson/html/test.php(50): getFeed(’http://feeds.fe…’) #2 {main} thrown in /home/content/c/r/a/craigohobson/html/test.php on line 7

    anyone? Thanks!


  28. Taylor Satula October 22nd

    I’ve Always Wondered How To do this

    @Jeffrey
    Can I Suggest A Tut. A Most Talkative Users List.


  29. Jeffrey Way October 22nd

    @Robert - I agree. SimplePie is great.

    But, I think we can all agree that it’s important to know how to do something before you take short cuts. :)


  30. Robert October 22nd

    @Jeffrey Way - absolutely agree that covering the basics from the ground up is a great learning experience. Thanks for reminding me of that.

    Once people get this going some of them might start wanting more functionality. That’s where something like SimplePie can come in handy. For example it handles Atom feeds as well (since there was a comment here about that). Oh and we forgot to mention, best of all it’s free :).


  31. Chris October 22nd

    I think this was a great beginning tutorial, it is going in my list of tutorials i got bookmarked. I think the important thing is to start out with the basics go back and look at it from an object oriented way. building methods classes and subclass objects as needed. Doing so in this manner will help build your toolbox of things that can be used and updated with new features ie rss to atom and what ever comes next.

    This is the strength and meaning behind write it once. Keep up the great work. Got any upcoming articles that we should keep our eyes out for?

    Chris McIntosh


  32. Jose October 22nd

    Wow This is quite similar to what i did no my site last week. Mine just loads a frontpage and when you click on a site link its loads the 10 last feed with ajax (with a simplepie php file).

    This is nice too :)


  33. Ivan October 23rd

    Finally something interesting :-)


  34. Chris Stubbs October 23rd

    Great tutorial.

    There was one thing on Line 4 in the myScript file in both the source files and on this page that caused a little hiccup on my server settings:

    $(’ul li a’).click(function() {

    I’m not sure about how other sites are doing or how the demo is, but when I tried it on my site it gave every list link the ’selected’ property and made it impossible to go to the urls. If anyone else got the same thing, the links would just go bold instead of taking you to the url. To fix it change the line to:

    $(’ul#nav li a’).click(function() {

    Make sure to add the #nav so the function specifically knows to only do it to that specific list.

    And if you don’t know the curl function then change :
    $content = file_get_contents($feed_url);

    To:
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $feed_url);
    $content = curl_exec($ch);
    curl_close($ch);

    This is by no means the definitive way to do it, but it works. It might benefit to specify a timeout.


  35. eric October 25th

    great post man thanks
    http://www.digital3dmx.com


  36. Pat Arlt October 26th

    This is a fun tutorial to turn into other stuff like a standerds complaint twitter feed with no script tags.

    Awesome tut I’m going to have fun with this one for awhile.


  37. medoo October 26th

    greaaaaaaaat ,

    BUT LINKS NOT WORKING !!!!!!!!!!!!!!!!!!!!!!!

    I WILL NEVER GO TO THE NEWS LINK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


  38. Yosi October 26th

    THANKS YOU JEFF!!!!!!
    GOOD WORK & TUTORIALS !!

    But,I got one problem,
    $(function () {
    $(’#admin-pages div:not(:first)’).hide();

    $(’ul li a’).click(function() {
    $(’ul#nav li a’).removeClass(’selected’);
    $(this).addClass(’selected’);

    var href = $(this).attr(’href’);
    var split = href.split(’#');

    $(’#admin-pages div’).hide(”slow”);
    $(’#admin-pages div#’ + split[1]).show(”slow”);

    return false;
    });
    });

    I changed it to my properties,
    I click the buttons and it only addClass and don’t remove the class for example if I have “Home About” and I will click on “Home” and then “About” both of them will be selected.


  39. Takumi86 October 26th

    wow nice tutorial, good job, but aren’t these for Wordpress only?


  40. MD October 28th

    Thnx for this tut! :)

    BTW… Upload it to imeem… :D


  41. THEMOLITOR October 28th

    Awesome tutorial!!!!

    For some reason the links to the feeds don’t do anything.

    My testing site for this tool: http://www.factcomics.com/rss

    PLEASE HELP! I LOVE THIS TOOL AND WANT IT TO WORK!!!


  42. THEMOLITOR October 29th

    I just noticed that the links don’t work in this demo too. Help please…


  43. Jeffrey October 29th

    @TheMolitor - That’s my mistake. In the Javascript file, you’ll see $(’ul li a’).click(function()…

    This is selecting ALL anchor tags within unordered lists. In this case, we only want to select the anchor tags that are within the unordered list with an id of #nav.

    So change that line to:

    $(’ul#nav li a’).click(function()….

    That’ll take care of it. Sorry about that! I’ll update the posting right now. Good eye!


  44. Sean O' Grady November 7th

    How do you limit the amount of feeds coming in?


  45. Jeffrey Way November 7th

    @Sean - You could add an “i” variable and do something like…

    $i = 0;
    while (bla bla) {
    pull individual article code
    $i++;
    if ($i == 5) break;
    }


  46. THEMOLITOR November 10th

    Thanks Jeffrey!


  47. THEMOLITOR November 10th

    I may have spoken too soon…I made the change, but now the tabs don’t switch between the different content when clicked???


  48. PHPLONDON November 11th

    The Video On Blip.tv doesn’t work???????? I’ve tried several times!! Jeff can you please embed the Video asap so i can watch it??

    Just found out about this site on a forum WOW! keep up the good work. This is now my most favourite site ;-)

    PHPLONDON


  49. Chris Geo November 22nd

    when doing something similar for my site a year ago i used cron jobs to run the fetch rss script which grabbed the rss content from multiple sites every 15 mins and stored them in a xml file. I then included the xml file content in the html page which I was supposed to saved loads in bandwidth and page load time only running the script once every 15 rather then ever page view. Seems to me this method shown in the video will make requests across the web on every page view so if you have a high traffic site your server will get rapped. Am I wrong?


  50. sarm December 8th

    for those of your wondering why it doesnt work that is because he hasnt told us what class file to include. how on earth are we supposed to know?


  51. indrajit December 17th

    it helped me to use other tools, flash wizards


  52. NinNin December 31st

    Work well but not with feedburner url.


Add Your Comment

( GET A GRAVATAR )
  • Gravatar

    Your Name January 9th

Arrow