Monday, May 27, 2013

Generate RSS feed with PHP

Generating RSS feed with PHP is vey easy. We need to maintain the basic RSS XML format in the output.

<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0'>
<channel>
<title> Any Title</title>
<link> Any URL </link>
<description> Any Description </description>
<lastBuildDate> Last Build Date</lastBuildDate>
<atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml" />
<language>en-us</language>

<item>
<title> Item1 Title</title>
<link> Item1 URL </link>
<description> Item1 Description </description>
</item>

<item>
<title> Item2 Title</title>
<link> Item2 URL </link>
<description> Item2 Description </description>
</item>

</channel>
</rss>


The above XML shows two feed items enclosed within "<item>" tags and each item has its own "title", "link" and "description" tags. The whole item-node construct is enclosed in <channel> and <rss> tags which is important. The "<atom:link ...." tag is totally optional and it's href property should hold the URL of current feed. Using such "<atom:link>" tag has some advantage of being portable and easier to cache. RSS 2.0 requires "title", "link" and "description" tags to be present in the output whereas Atom 1.0 requires "id","title", "link", "author", "updated" elements.

Now, suppose we have a DB table called 'article' with fields 'title', 'url' and 'description' and 'content' fields. We would be making a simple SELECT query, then iterate though the rows and create the final XML as displayed in the PHP program below ::

<?php
// Database Stuffs
$con = mysql_connect("localhost","root","");
mysql_select_db("test");
$sql = "Select title, url, description from article";
$res = mysql_query($sql);

$xml_data = "";

// MAIN LOOP starts
while( $row = mysql_fetch_array($res))
{
  $xml_data .= "<title>". htmlentities($row['title']) ."</title>";
  $xml_data .= "<link>". htmlentities($row['url']) ."</link>";
  $xml_data .= "<description>". htmlentities($row['description']) ."</description>";
}

// Set the output document type through header() function
header("Content-Type: application/rss+xml; charset=utf-8");

// Next, GENERATE the RSS Content
echo '<?xml version="1.0" encoding="utf-8"?>';
echo '<rss version="2.0">';
echo '<channel>';
echo '<title> All Article Listings</title>';
echo '<link>http://www.example.org/aticle-listing-rss.php</link>';
echo '<description>Get Listing of all Articles</description>';
echo '<lastBuildDate>' . date('d M Y h:i:s ') . '+0000' . '</lastBuildDate>';
echo '<language>en</language>';

// Render the DB content
echo $xml_data;

// Concluding Tags
echo '</channel>';
echo '</rss>';
?>


The above code is very simple and easy to understand. However some output characters like single quote or ampersand can cause error. That's why we have used htmlentities() function to convert them to HTML compatible. After we create an RSS feed this way, we may get it checked by validator.w3.org. The output on firefox is shown below ::



If we want to include any article images in the output we can do it two ways :

$xml_data .= "<description>". htmlentities("<a href='". $row['link'] ."'><img src='". $row['image'] ."'></a>") ."</description>";

We created the <img> tag enclosed in an anchor tag to linkify the image. We used htmlentities() function to make these data not available for XML parsing. Characters like "<" and "&" are illegal in XML elements. htmlentities() function would convert <img> to "&lt;img&gt;" which then would not be parsed as XML node. But browser can still build the <img> tag and show the corresponding image on screen in the output.

Similar effect we can achieve through using "CDATA". Check the code below.

$xml_data .= "<description>"  . "<![CDATA[<a href='". $row['link'] ."'><img src='". $row['image'] ."' ></a>]]>" . "</description>";

A CDATA section within XML document starts with "<![CDATA[" and ends with "]]>" and hence it can not contain the string "]]>". Nested CDATA section are also not allowed. Texts like Javascript code should be placed inside CDATA section in XML document.

Download: Fast, Fun, Awesome

No comments: