Overview
An RSS feed is an XML format that is great for sharing and broadcasting content such as news, articles, events, etc. There are a number of feed readers (or “aggregators”) available for users to access multiple RSS feeds from one location. Most modern web browsers support RSS feeds, as well.
Inside every RSS feed there are at least two elements: channel, which provides information about the feed itself, and one or more items, which provide information about the content the feed represents.
If you have a blog or some other kind of publishing system, chances are it uses a database. With the Dynamic RSS PHP class, you can easily add an RSS feed using the information that’s stored in your MySQL database. Here’s a sample of what the code looks like. It may appear intimidating at first, but it’s actually quite easy. I’ll go over everything right after the example.
<?php
include("DynamicRSS.class.php");
$rss = new DynamicRSS();
$rss->db('localhost', 'dbname', 'dbuser', 'dbpass')
->query("
SELECT id,
title,
CONCAT(email, ' (', author, ')') as author,
article,
DATE_FORMAT(article_date, '%a, %d %b %Y %H:%i:%s EST') as pubDate,
'http://example.com/article?id={{id}}' as link
FROM articles
ORDER BY article_date DESC
LIMIT 10
")
->channel( array(
'title'=>'Example RSS Feed',
'link'=>'http://example.com/',
'description'=>'The best RSS feed you will ever encounter',
'language'=>'en-us',
'copyright'=>'Copyright 2008 Example.com',
'managingEditor'=>'editor@example.com (Editor Name)',
'ttl'=>60
))
->image('http://example.com/images/logo.png', 200, 100)
->item( array(
'title'=>'title',
'link'=>'link',
'author'=>'author',
'description'=>'article',
'guid'=>'link',
'pubDate'=>'pubDate'
))
->generate();
?>
Implementing the DynamicRSS class
The DynamicRSS class supports method chaining, which makes it possible to generate your RSS feed in just two PHP statements. The first statement simply creates the DynamicRSS object. Let’s take a look at the methods being used in the second statement.
- The db() method is used to setup a connection to your database.
- The query() method defines the query that will pull information from your database
- The channel() method defines information about your feed
- The image() method lets you associate an image with your feed
- The item() method defines information about the feed’s content
- The generate() method produces the feed
Hopefully, that breakdown makes it seem a bit easier. Now, let’s look at a few specifics.
Creating Your Query
To the query() method, I’m passing a MySQL statement that will pull the 10 most recent articles from my database. The fields returned by this query will be used to generate items in the feed, so it’s important that they are formatted properly. For a valid RSS feed, the author field (and any other field requiring an email address) should be formatted as author@example.com (Author’s Name). In this case, since the email and the author’s name are stored in two separate fields, I’m using the CONCAT() function to produce the appropriate format:
CONCAT(email, ' (', author, ')') as author
You might also notice that I’m doing something strange with the publication date:
DATE_FORMAT(article_date, '%a, %d %b %Y %H:%i:%s EST') as pubDate
This simply formats a MySQL datetime field as an RFC 822 compliant date/time representation, which is required by the RSS 2.0 standard.
There’s also something strange going on with my link field:
'http://example.com/article?id={{id}}' as link
The {{id}} is referencing the id field of the same row in the same database table. This is useful because you’re going to want to link people to your articles from your RSS feed but, being dynamic and all, the page you will have to link to will change with each article. You can reference any field name in the query() method using the same curly bracket syntax described above.
Defining Your Channel
To the channel() method, I’m passing an array containing a list of element names and values that will be used in the feed. You can pass any of the valid channel elements in this array, but make sure you pass at least the title, link, and description, as those are required by the RSS 2.0 standard.
Associating an Image
The image method is optional, but when used will associate an image with your feed. The first paramter is a URL to the image. The second and third parameters are width and height, respectively.
Creating Items
To the item() method, I’m passing another array. This time, the array contains a list of elements that will be used to generate items in the RSS feed. Each array key represents the name of an item sub-element, and the corresponding value is the name of the corresponding database field to use:
array(
'title'=>'title_field',
'link'=>'link_field',
'author'=>'author_field',
);
This will create each item in your RSS feed with three sub-elements:
<item>
<title>Example Title</title>
<link>http://example.com/article.php?id=1234</link>
<author>John Doe</author>
</item>
Here is a list of valid item elements from the RSS 2.0 specification.
Note that each value in your array must be the name of a field in the database. But what if, for example, you are the author of all your articles and you designed your database without an author field? Simple, just fake one in your query:
SELECT id, title, 'John Doe' AS author, article_date, ...
In similar ways, you should be able to manipulate your query enough in pure SQL to accommodate your feed.
Generating the Feed
The generate() method, by default, outputs the RSS feed. This should be the very first output that occurs on the calling page, otherwise you will receive an error. Note that you can modify the output of this method by passing ‘string’ as a parameter. This will return the XML data as a string that you can store in a variable.
Method Table
Now that we’ve covered the basics, here’s a comprehensive method table that will provide some enhanced functionality for advanced users:
| Method | Parameters | Description | |
|---|---|---|---|
| db() | host, name, user, pass | Setup a connection to a MySQL database. All parameters are required. | Required |
| query() | query | A string representing the SQL query to be executed. This query should return all of the items (articles, events, etc.) that you wish the feed to produce. Use {{fieldname}} to reference database field names in the same row. | Required |
| feed_url() | url | Sets the absolute URL of the RSS feed file. By default, this value is guessed by the class. You can override the default with this method, but typically you will never have to call it. | Optional |
| indent() | string | Sets the indent character (or string). The default is four spaces. To disable indents, use ” | Optional |
| channel() | array | Creates one or more sub-elements of the <channel> element. Array keys indicate sub-element names and corresponding values indicate the sub-element values. Required channel sub-elements include title, link, and description. See the specification for a list of optional elements. Note: sub-elements with attributes, such as cloud and textInput are not supported. See the channel_xml() method for more information. | Required |
| channel_xml() | string | A string containing raw XML data to include in the channel element. This method can be used to to add unsupported sub-elements, such as cloud and textInput. | Optional |
| image() | url, [width, height] | Used to associate an image with the feed. Width and height cannot exceed 144 and 400 pixels, respectively, per the RSS 2.0 standard. The image title and description assume the value of the channel title and description, so this method should be called after the channel() method. | Optional |
| item() | array | Defines the structure of all feeds items to be produced. Array keys indicate sub-element names and the corresponding values indicate the name of the database field to use. | Required |
| item_xml() | string | A string containing raw XML data to include in each item element. This method can be used to create sub-elements that require attributes, which are unsupported by the item() method. Use {{fieldname}} to reference database field names in the same row. | Optional |
| generate() | [output] | Generates the RSS feed. This should be the final method executed. Default output is to the screen, and should be the very first output that occurs on the calling page. To capture the XML data in a variable, set output equal to ‘string’. | Required |
All of these methods can be chained as shown in the first example.
Download
Download the current version of the DynamicRSS PHP class: Version 1.0
This class is provided to you as-is, at absolutely no cost. If you would like to support its development, feel free to contribute any amount you prefer via PayPal. As always, you are welcome to contribute code for bug fixes and feature enhancements as well. Either way, thanks for supporting our efforts!
Known Issues
- Relative URLs will fire a warning in the feed validator. It is preferred to use absolute URLs in all of your articles for best compatibility with feed reading devices.
- The class currently uses htmlentities() to encode special characters. This function will not invalidate a feed, but it needs to be replaced with a similar xmlentities() function for optimal compatibility.
Please report any bugs you find using our contact form.
Resources
- Official RSS 2.0 documentation
- Required Channel Elements
- Optional Channel Elements
- Item Elements
- Atom and RSS FEED Validator
Licensing
This software is licensed under the GNU General Public License.
I’ve been searching a while for a good rss class script to modify one of my sites. Our site has a series of articles in various categories and I’ve been able to run the The DynamicRSS PHP Class so that I can obtain the latest RSS feeds for each category. But I’m scratching my head on one wee little obstacle.
My query that I use calls for the categoryname but I cannot figure out how to incorporate it into the channel array so that my different category feeds can have their appropriate category name within the channel title.
@Marv: can you get the category name in a variable and pass it to the channel() method?
In my situation, in garnering the category name in the original query meant doing a left join between two tables … one table where the articles are … and the other where the categories are (the names of the categories). This initial query using the join is necessary to get the articles grouped in their respective categories.
After a little monkeying around, I made a separate mysql query for the category name directly from its own table and made a variable for it. Passing that variable into the channel() worked perfectly.
Thank you for the heads up on that. :)