9.2. Creating an RSS Feed

RSS feeds follow a general format that allows for large-scale, easy compatibility with any feed reader in use right now. The basic format for an RSS consists of a channel that includes a title, description, link, and language setting.

Within the channel, you declare each entry as an item. Each item contains a title, description, link, the date it was published, and a unique identifier.

To create your feed, you need to create a new folder and file in the simple_blog project. Next, add a new folder called feeds, and then create a new file called rss.php and in that folder (the full path: http://localhost/simple_blog/feeds/rss.php).

Before you can run your file, you need to modify .htaccess. This is as simple as adding an additional file extension to the first RewriteRule that prevents any rewrite from occurring if a file ending in .php is accessed. To accomplish this, add the following line in bold to your .htaccess file:

RewriteEngine on
RewriteBase /simple_blog/

RewriteRule .(gif|jpg|png|css|ico|swf|js|inc.php|php)$ - [L]
RewriteRule ^admin/?$ admin.php [NC,L]
RewriteRule ^admin/(w+)/?$ admin.php?page=$1 [NC,L]
RewriteRule ^admin/(w+)/([w-]+) admin.php?page=$1&url=$2 [NC,L]
RewriteRule ^(w+)/?$ index.php?page=$1
RewriteRule ^(w+)/([w-]+) index.php?page=$1&url=$2

9.2.1. Describing Your Feed

Now that your file is created and being handled properly, you can start to mark up your feed.

Begin by adding a Content-Type header to the document (using the aptly named header() function). This header tells the browser to serve the file as XML.

Next, you need to output an XML declaration. However, this causes issues because XML declarations conflict with PHP short tags. You can get around this by using the echo command to output the declaration in double quotes, which eliminates the conflict.

Now you need to state what you are doing, which you accomplish by adding an <rss> tag with a version attribute. This tells any feed reader what it's receiving and ensures the information received is handled properly.

Next, you add the channel declaration and your feed's basic information. As mentioned previously, the basic information consists of the title, description, link, and language of your feed.

Add the following code to rss.php to create your feed:

<?php

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

</channel>
</rss>

At this point, you can load your RSS feed in a browser to see what it looks like without any items; you can load the information at http://localhost/simple_blog/feeds/rss.php (see Figure 9-1).

NOTE

You don't want to do anything further with the feed as it appears in your browser. The blog is not available publicly, so subscribing to the feed won't work in a feed reader at this time.

Figure 9.1. Your feed as it appears in Firefox 3 on a Mac

9.2.2. Creating Feed Items

Now that your feed is working properly, you need to add your blog entries as feed items. This process is similar to the way you display your entries in index.php, except that you simplify the process by displaying only the latest blog entries (your feed will send data to the browser in only one way, unlike index.php, which has view options for multiple pages, entry previews, and full entries).

9.2.2.1. Using Existing Functions to Minimize Effort

You've already written a function to retrieve your entries from the database, so you don't need to write a new one. Including functions.inc.php in rss.php enables you to access retrieveEntries(), which you use to return all of your blog entries as an array. Next, you can loop through the entries to generate your feed items.

For retrieveEntries() to work, you also need a database connection to exist. For this, you include db.inc.php in rss.php as well. After you include the necessary files in rss.php, you open a database connection by inserting the code in bold at the very top of the file:

<?php

// Include necessary files
include_once '../inc/functions.inc.php';
include_once '../inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

</channel>
</rss>

Next, you need to load the entries from the database. You do this by storing the return value of retrieveEntries() in a variable called $e. Also, retrieveEntries() attaches a $fulldisp flag to the end of the returned array, so you want to pop the last element off $e to remove the flag. You can accomplish this using array_pop(). Finally, you need to do some basic data sanitization before you try to output anything, just to be on the safe side.

Do this by adding the code in bold to rss.php:

<?php

// Include necessary files
include_once '../inc/functions.inc.php';
include_once '../inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);

// Load all blog entries
$e = retrieveEntries($db, 'blog'),

// Remove the fulldisp flag
array_pop($e);

// Perform basic data sanitization
$e = sanitizeData($e);

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

</channel>
</rss>

At this point, you have an array that contains your entries ready for output. You use a foreach loop to display each entry.

Begin by generating an item with a title, a description, and a link. The only extra step is to escape all HTML entities in your description—you need to convert special characters to their HTML entity equivalents, such as < to &lt;. This is necessary because unescaped HTML will cause an error for RSS readers. You accomplish this by calling htmlentities() on the contents of the entry column.

Add the following code in bold to rss.php:

<?php

// Include necessary files
include_once '../inc/functions.inc.php';
include_once '../inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);

// Load all blog entries
$e = retrieveEntries($db, 'blog'),

// Remove the fulldisp flag
array_pop($e);

// Perform basic data sanitization
$e = sanitizeData($e);

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

<?php

// Loop through the entries and generate RSS items
foreach($e as $e):
    // Escape HTML to avoid errors
    $entry = htmlentities($e['entry']);

    // Build the full URL to the entry
    $url = 'http://localhost/simple_blog/blog/' . $e['url'];

?>
    <item>
        <title><?php echo $e['title']; ?></title>
        <description><?php echo $entry; ?></description>
        <link><?php echo $url; ?></link>
    </item>

<?php endforeach; ?>

</channel>
</rss>

To keep your script as legible as possible, you need to use the alternative syntax for your foreach loop, using a colon to start the loop and endforeach to close the loop.

You can see your feed items displayed if you load http://localhost/simple_blog/feeds/rss.php into your browser at this point (see Figure 9-2).

Figure 9.2. Your feed with items, as displayed in Firefox 3

On the most basic level, your RSS feed is now running. However, you still need to add a couple things to feed items to ensure widespread compatibility with feed readers: a GUID and a publishing date.

9.2.2.2. What Is a GUID?

In RSS, publishers are encouraged to include a Globally Unique Identifier (GUID). There is no hard-and-fast rule for what to use as an item's GUID, but the most common GUID tends to be the permanent URL of the item because this is generally a unique path that won't be duplicated.

In your feed, you use each item's URL as a GUID, which means that adding it is as simple as including a second element that displays the link value. It's not uncommon for RSS feed items to have identical link and GUID values.

You can insert a GUID by adding the code in bold to rss.php:

<?php

// Include necessary files
include_once '../inc/functions.inc.php';
include_once '../inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);

// Load all blog entries
$e = retrieveEntries($db, 'blog'),

// Remove the fulldisp flag
array_pop($e);

// Perform basic data sanitization
$e = sanitizeData($e);

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

<?php

// Loop through the entries and generate RSS items
foreach($e as $e):
    // Escape HTML to avoid errors
    $entry = htmlentities($e['entry']);

    // Build the full URL to the entry
    $url = 'http://localhost/simple_blog/blog/' . $e['url'];

?>
    <item>
        <title><?php echo $e['title']; ?></title>
        <description><?php echo $entry; ?></description>
        <link><?php echo $url; ?></link>
        <guid><?php echo $url; ?></guid>
    </item>

<?php endforeach; ?>

</channel>
</rss>

9.2.2.3. What Is a Publishing Date?

The publishing date of a feed item is the date it was created on. RSS requires that this date conform to the RFC-822 guidelines, which means the date must be formatted as follows:

Sat, 23 May 2009 18:54:16 −0600

You might remember that, when you created your entries table, you included a column called created that stores the date automatically when an entry is created. However, as things stand now, the created column isn't returned from retrieveEntries(). Before you can generate a publishing date for your feed items, you need to add the created column to the array of values returned from retrieveEntries().

9.2.2.3.1. Modifying retrieveEntries() to Return the created Column

Your first task is to add the created column to the array returned from retrieveEntries(). To do this, you simply need to add the created column to your SQL query. Do this by opening functions.inc.php and modifying the lines in bold in retrieveEntries():

function retrieveEntries($db, $page, $url=NULL)
{
    /*
     * If an entry URL was supplied, load the associated entry
     */
    if(isset($url))
    {
        $sql = "SELECT id, page, title, image, entry, created
                FROM entries
                WHERE url=?
                LIMIT 1";
        $stmt = $db->prepare($sql);
        $stmt->execute(array($url));

        // Save the returned entry array
        $e = $stmt->fetch();

        // Set the fulldisp flag for a single entry
        $fulldisp = 1;
    }

    /*
     * If no entry ID was supplied, load all entry titles for the page
     */
    else
    {
        $sql = "SELECT id, page, title, image, entry, url, created
                FROM entries
                WHERE page=?
                ORDER BY created DESC";
        $stmt = $db->prepare($sql);
        $stmt->execute(array($page));

        $e = NULL; // Declare the variable to avoid errors

        // Loop through returned results and store as an array
        while($row = $stmt->fetch()) {
            if($page=='blog')
            {
                $e[] = $row;
                $fulldisp = 0;
            }

else
            {
                $e = $row;
                $fulldisp = 1;
            }
        }

        /*
         * If no entries were returned, display a default
         * message and set the fulldisp flag to display a
         * single entry
         */
        if(!is_array($e))
        {
            $fulldisp = 1;
            $e = array(
                'title' => 'No Entries Yet',
                'entry' => 'This page does not have an entry yet!'
            );
        }
    }

    // Add the $fulldisp flag to the end of the array
    array_push($e, $fulldisp);

    return $e;
}

9.2.2.3.2. Creating a pubDate from the MySQL Timestamp

Now your entry array contains the MySQL timestamp that was generated when each entry was created. However, the MySQL timestamp is formatted like this:

2009-05-23 18:54:16

Using the MySQL timestamp renders your RSS feed invalid, so you need to somehow convert it to the proper RFC-822 format. Fortunately, PHP provides two functions that allow you to do exactly that: strtotime() and date().

This means that string to timestamp—strtotime()—can convert a variety of date strings, including your MySQL timestamp, to a UNIX timestamp. You can then use the UNIX timestamp in the date() function, which accepts a format and a timestamp and outputs a formatted date string.

RSS is widely used, so PHP provides a constant for use with date() that returns a properly formatted RFC-822 date string, called DATE_RSS.

The next step is to add the code in bold to rss.php to reformat your date and add a publishing date to each item:

<?php

// Include necessary files
include_once '../inc/functions.inc.php';
include_once '../inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);

// Load all blog entries
$e = retrieveEntries($db, 'blog'),

// Remove the fulldisp flag
array_pop($e);

// Perform basic data sanitization
$e = sanitizeData($e);

// Add a content type header to ensure proper execution
header('Content-Type: application/rss+xml'),

// Output the XML declaration
echo "<?xml version="1.0" encoding="UTF-8"?>
";

?>
<rss version="2.0">
<channel>

    <title>My Simple Blog</title>
    <link>http://localhost/simple_blog/</link>
    <description>This blog is awesome.</description>
    <language>en-us</language>

<?php

// Loop through the entries and generate RSS items
foreach($e as $e):
    // Escape HTML to avoid errors
    $entry = htmlentities($e['entry']);

    // Build the full URL to the entry
    $url = 'http://localhost/simple_blog/blog/' . $e['url'];

    // Format the date correctly for RSS pubDate
    $date = date(DATE_RSS, strtotime($e['created']));

?>
    <item>
        <title><?php echo $e['title']; ?></title>
        <description><?php echo $entry; ?></description>
        <link><?php echo $url; ?></link>
        <guid><?php echo $url; ?></guid>
        <pubDate><?php echo $date; ?></pubDate>
    </item>

<?php endforeach; ?>

</channel>
</rss>

Your feed now contains all the elements it needs to be compatible with nearly all feed readers. When you load http://localhost/simple_blog/feeds/rss.php in a browser, you see your items displayed with the date they were published (see Figure 9-3).

Figure 9.3. Your feed as it appears in Firefox 3, complete with the publishing date

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.202.27