Get in Contact
Name:

Email:

Subject:

Message (no HTML):

Elsewhere on the Web

I can also be found at the following sites. Click on an image or text link to visit.


DigitalSpy Forums | Talk Photography

create an rss feed with php, mysql and apache 16 Jun '09, 20:13

It's taken me a long time to get a standards compliant RSS feed of my blog available simple because I didn't know how to do it. Two days ago I discovered how, and realised it really wasn't that hard.

The Aim - Compliant RSS

The first thing to do before trying to create the required XML, is to look at the structure of a feed so that we know what the finished article will look like;

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://www.example.com/rss/feed.xml" rel="self" type="application/rss+xml" />
    <title>Feed Title</title>
    <link>http://www.example.com</link>
    <description>A description of the feed</description>

    <item>
      <title>Article title</title>
      <guid>http://www.example.com/article?id=1234</guid>
      <link>http://www.example.com/an-interesting-story/</link>
      <description>The quick brown fox jumps over the lazy dog.</description>
    </item>
  </channel>
</rss>


Above is an example of RSS. We can break this down into two main parts. The first part describes the feed itself. This is the part ending with </description>, just before the <item> tag.

The second part, commencing with <item> and ending with </item> is one of the articles contained within the feed. These item tags are repeated for each article. In my blog, I have 10 <item> tags, describing the last 10 blog entries on my site.

PHP Code

So let's move away from the actual XML code for the time being and focus on getting the data from MySQL. At this point I'm assuming that you know about MySQL and have an appropriate populated database. If not, get searching on the internet to find out about how to get this first.

This is an example of completed PHP code:

<?php
header("Content-Type: application/xml; charset=ISO-8859-1");

$server  = "xxx.xxx.xxx.xxx";						
$dbuser  = "username";	
$dbpass  = "password";
$dbname  = "database";
$conn = mysql_connect( $server, $dbuser, $dbpass, TRUE ) or die(mysql_error()));
$rs   = mysql_select_db( $dbname, $conn ) or die(mysql_error()));

$sql = 'SELECT * FROM table ORDER BY date DESC LIMIT 10';
$rs = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_array($rs))
	{
	$uid = $row[0];
	$title = $row[1];
	$description = $row[2];
	$urltitle = $row[3];

	$output .= '<item>';
	$output .= '<title>' . $title . '</title>';
	$output .= '<guid>http://www.example.com/article?id=' . $euid . '</guid>';
	$output .= '<link>http://www.example.com/' . $urltitle . '/</link>';
	$output .= '<description>' . $description . '</description>';
	$output .= '</item>';
	}
?>


NOTE: All PHP code should start with <?php and end with ?>

The line beginning "header..." is of critical importance, and the reason why I didn't figure out that RSS could be done this way for so long. It tells the browser what sort of file it is. By leaving it out, the browser will just take it as a PHP file but by putting this line before any other output ensures it is treated as XML.

PHP Code - Connecting to the Database

The next four lines set four variables - $server, $dbuser, $dbpass and $dbname. These will store the logon details for the MySQL database. $server is the IP address of the server. $dbuser is your username. $dbpass is your password and $dbname is the name of the database.

The next two lines deal with actually making the connection to the database.

Now, ideally these six lines (repeated below for clarity) should not be placed within the feed file. They should be stored in a second PHP file located in a non public area of your website and referenced by using the include() command in the main PHP script.

$server  = "xxx.xxx.xxx.xxx";						
$dbuser  = "username";	
$dbpass  = "password";
$dbname  = "database";
$conn = mysql_connect( $server, $dbuser, $dbpass, TRUE ) or die(mysql_error()));
$rs   = mysql_select_db( $dbname, $conn ) or die(mysql_error()));


PHP Code - Querying the Database

Now we have a connection to MySQL, we can query the database. In layman's terms - we're getting the data out from the server so that we can place it into the RSS feed.

$sql = 'SELECT * FROM table ORDER BY date. DESC LIMIT 10';
$rs = mysql_query($sql) or die(mysql_error());


First we assign our SQL query to a variable - in this case $sql. The query shown tells MySQL to look at the table named 'table', and give us all of the fields within that table (*) ordered by date in descending order (that is, newest first) with a limit of 10 records.

The second line executes the query, but we can't access the data directly at this point.

PHP Code - Getting to the Data

The next block of code is quite a big one. This is a loop that takes the results of the query and goes through them one by one. So, in this example, the code will loop 10 times.

while ($row = mysql_fetch_array($rs))
	{
	$uid = $row[0];
	$title = $row[1];
	$description = $row[2];
	$urltitle = $row[3];

	$output .= '<item>';
	$output .= '<title>' . $title . '</title>';
	$output .= '<guid>http://www.example.com/article?id=' . $euid . '</guid>';
	$output .= '<link>http://www.example.com/' . $urltitle . '/</link>';
	$output .= '<description>' . $description . '</description>';
	$output .= '</item>';
	}


The first line in this block sets the conditions of the loop. It is important to note the brackets ({ }) in this block of code. The code that will be looped through starts with an open bracket, and ends with a close bracket.

Each field can be referenced through the variable $row. $row[0] is the first field, $row[1] the second and so on. The first 4 lines in the looping block of code assign friendly names to these variables.

We now (finally) get to building a section of XML - the <item></item> block. The six lines commencing with $output all assign data to that variable. Notice the dot before the equals sign. This means that data is appended to the variable, so that by the time the 6th line has finished, $output contains all the data within the <item></item> block.

By the time this code has finished looping (10 times in this example), $output will contain multiple <item></item> blocks. We are now ready to put it into the XML.

After the PHP code - the XML file

Now, the XML data needs to be put into the file. This must start after the closing PHP tag ?>.

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://www.example.com/rss/feed.xml" rel="self" type="application/rss+xml" />
    <title>Feed Title</title>
    <link>http://www.example.com</link>
    <description>A description of the feed</description>
		
    <?php echo $output ?>
  </channel>
</rss>

This is pretty similar to the code shown right at the beginning of these instructions. The only difference here is the presence of the line <?php echo $output ?> instead of any <item></item> tags. This is because those <item></item> blocks are contained within the PHP variable $output. This new line simply echos (or displays) the contents of that variable. Therefore when the client software reads the file, it will see the full XML and identify it as RSS.

The entire file

The entire completed file will look something like this:

<?php
  header("Content-Type: application/xml; charset=ISO-8859-1");

  $server  = "xxx.xxx.xxx.xxx";
  $dbuser  = "username";	
  $dbpass  = "password";
  $dbname  = "database";

  $conn = mysql_connect( $server, $dbuser, $dbpass, TRUE ) or die(mysql_error()));
  $rs   = mysql_select_db( $dbname, $conn ) or die(mysql_error()));

  $sql = 'SELECT * FROM table ORDER BY date DESC LIMIT 10';
  $rs = mysql_query($sql) or die(mysql_error());

  while ($row = mysql_fetch_array($rs))
    {
    $uid = $row[0];
    $title = $row[1];
    $description = $row[2];
    $urltitle = $row[3];

    $output .= '<item>';
    $output .= '<title>' . $title . '</title>';
    $output .= '<guid>http://www.example.com/article?id=' . $euid . '</guid>';
    $output .= '<link>http://www.example.com/' . $urltitle . '/</link>';
    $output .= '<description>' . $description . '</description>';
    $output .= '</item>';
    }
?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://www.example.com/rss/feed.xml" rel="self" type="application/rss+xml" />
    <title>Feed Title</title>
    <link>http://www.example.com</link>
    <description>A description of the feed</description>

    <?php echo $output ?>
  </channel>
</rss>


Changing the name from feed.php to feed.xml

You may consider that providing a feed URL ending in PHP doesn't look quite right. A rule can be written in the configuration file of the Apache webserver that states that accessing feed.xml translates to accessing feed.php. The user will see feed.xml, but the server will provide feed.php.

No related blog entries
No related links to display
No attachments to display
No comments to display
* Cookies are required to submit comments
Name:

Email:

Comment (no HTML or BBcode):


Last.fm: Last played:

03 Sep '10, 19:10
Jimi Hendrix – Bleeding Heart

Last Microblog Post:

22 Aug '10, 21:03 via Identi.ca
m0gky: Got an #XBox today, but having problems with #XBoxLive. Just me or anyone else? Re port forwarding, is incoming on 80 required?