Since there is absolutely no documentation on how to use PHP5's XMLWriter class, here is a very simple example of how to use the class to create an rss feed.

<?php

// THIS IS ABSOLUTELY ESSENTIAL - DO NOT FORGET TO SET THIS
@date_default_timezone_set("GMT");

$writer = new XMLWriter();
// Output directly to the user

$writer->openURI('php://output');
$writer->startDocument('1.0');

$writer->setIndent(4);

// declare it as an rss document
$writer->startElement('rss');
$writer->writeAttribute('version', '2.0');
$writer->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');


$writer->startElement("channel");
//----------------------------------------------------
//$writer->writeElement('ttl', '0');
$writer->writeElement('title', 'Latest Products');
$writer->writeElement('description', 'This is the latest products from our website.');
$writer->writeElement('link', 'http://www.domain.com/link.htm');
$writer->writeElement('pubDate', date("D, d M Y H:i:s e"));
	$writer->startElement('image');
		$writer->writeElement('title', 'Latest Products');
		$writer->writeElement('link', 'http://www.domain.com/link.htm');
		$writer->writeElement('url', 'http://www.iab.net/media/image/120x60.gif');
		$writer->writeElement('width', '120');
		$writer->writeElement('height', '60');
	$writer->endElement();
//----------------------------------------------------



//----------------------------------------------------
$writer->startElement("item");
$writer->writeElement('title', 'New Product 8');
$writer->writeElement('link', 'http://www.domain.com/link.htm');
$writer->writeElement('description', 'Description 8 Yeah!');
$writer->writeElement('guid', 'http://www.domain.com/link.htm?tiem=1234');

$writer->writeElement('pubDate', date("D, d M Y H:i:s e"));

$writer->startElement('category');
	$writer->writeAttribute('domain', 'http://www.domain.com/link.htm');
	$writer->text('May 2008');
$writer->endElement(); // Category

// End Item
$writer->endElement();
//----------------------------------------------------


// End channel
$writer->endElement();

// End rss
$writer->endElement();

$writer->endDocument();

$writer->flush();
?>

The above will give you this:

<?xml version="1.0"?> 
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> 
<channel> 
 <title>Latest Products</title> 
 <description>This is the latest products from our website.</description> 
 <link>http://www.domain.com/link.htm</link> 
 <pubDate>Thu, 10 Jul 2008 11:47:14 GMT</pubDate> 
 <image> 
  <title>Latest Products</title> 
  <link>http://www.domain.com/link.htm</link> 
  <url>http://www.iab.net/media/image/120x60.gif</url> 
  <width>120</width> 
  <height>60</height> 
 </image> 
 <item> 
  <title>New Product 8</title> 
  <link>http://www.domain.com/link.htm</link> 
  <description>Description 8 Yeah!</description> 
  <guid>http://www.domain.com/link.htm?tiem=1234</guid> 
  <pubDate>Thu, 10 Jul 2008 11:47:14 GMT</pubDate> 
  <category domain="http://www.domain.com/link.htm">May 2008</category> 
 </item> 
</channel> 
</rss>

Just a note from an rss validator, this line should be before the 'channel' tag for some reason!

<atom:link href="http://dallas.example.com/rss.xml" rel="self" type="application/rss+xml" />

I will post another example below for the php5 XMLReader Class later.

    ...and here's how to use it as a pre made class...

    @date_default_timezone_set("GMT");
    
    
    class rss extends XMLWriter
    {
    	// $file = filename to output to
    	// $title = rss fed title
    	// $description = rss feed description
    	// $link = rss feed link
    	// $date = date of feed
    
    function __construct($file, $title, $description, $link, $date)
    {
    	// Start by calling the XMLWriter constructor...
    
    	$this->openURI($file);
    	$this->startDocument('1.0');
    	$this->setIndent(4);
    
    	$this->startElement('rss');
    		$this->writeAttribute('version', '2.0');
    		$this->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
    
    	$this->startElement("channel");
    		$this->writeElement('title', $title);
    		$this->writeElement('description', $description);
    		$this->writeElement('link', $link);
    		$this->writeElement('pubDate', date("D, d M Y H:i:s e", strtotime($date)));
    
    }
    
    // Send a multi-dimensional array
    // $array = 
    // 'title' = Item title
    // 'descritpion'
    // 'link'
    // 'guid' = unique id for item (should be a url)
    
    // 'category' = array of:
    // 'title'
    // 'domain'
    
    function addItem($array)
    {
    	if (is_array($array))
    	{
    		$this->startElement("item");
    		$this->writeElement('title', $array['title']);
    		$this->writeElement('link', $array['link']);
    		$this->writeElement('description', $array['description']);
    		$this->writeElement('guid', $array['guid']);
    
    		if (isset($array['date']))
    		{
    			$this->writeElement('pubDate', date("D, d M Y H:i:s e", strtotime($array['date'])));
    		}
    
    		if (isset($array['category']) && isset($array['category']['title']))
    		{
    			$this->startElement('category');
    				$this->writeAttribute('domain', $array['category']['domain']);
    				$this->text($array['category']['title']);
    			$this->endElement(); // Category
    		}
    	$this->endElement(); // Item
    	}
    
    }
    
    function _endRss()
    {
    	// End channel
    	$this->endElement();
    
    	// End rss
    	$this->endElement();
    
    	$this->endDocument();
    
    	$this->flush();
    }
    
    } // end class...
    

    ...and a sample on the class usage!

    // Sample usage of class...
    
    $item = array();
    $item['title'] = 'New product One';
    $item['link'] = 'http://www.domain.com/product1.htm';
    $item['description'] = 'A full description of product that is new.';
    $item['guid'] = 'http://www.domain.com/product1.htm'; // a unique http address will do!
    $item['date'] = date('Y-m-d'); //send any time of date!
    
    $item['category'] = array();
    $item['category']['title'] = 'CD Players';
    $item['category']['domain'] = 'http://www.domain.com/cdplayers.htm';
    
    $w = new rss('php://output', 'New Products', 'This month\'s new products', 'http://www.domain.com/link.htm', date('Y-m-d'));
    
    $w->addItem($item);
    
    $w->_endRss();

    You could use a destructor, but I think the '_endRss' is better.

    Next project... PHP XMLReader

      7 months later

      I'm just writing an extension to XMLReader - this will give you a good example of how to manipulate an RSS XML news feed for your website...

      I'll post a link here when it's ready...


      Web Design <- PHP Website Design & Programming

        9 months later

        In the example below (btw, thanks so much for this class and the details!), how would I make a looping section.

        I want to include a bunch of images in each $item and keep overwriting the variables...

        ie:

        <item>
        <title>Title</title>
        <link>link url</link>
        <images>
        <image>
        <title>image title</title>
        <url>imageurl</ul>
        </image>
        <image>
        <title>image title</title>
        <url>imageurl</ul>
        </image>
        <image>
        <title>image title</title>
        <url>imageurl</ul>
        </image>
        </images>
        </item>

        When I use the code below and the class, I only get one image (the last one from my while sql query results)

        When I make the array key->values unique by adding a counter (eg: key1->value1,key2->value2 etc) I get all my images under one <image>array data</image> instead of multiple <image>stuff from first record</image><image>stuff from second record</image> etc...

        Here is what I have done... perhaps you can help me with this concept.. I am not sure if XMLWriter supports what I am trying to do...

        
        if (isset($array['images']))
        			{
        				$this->startElement('media');
        
        					$this->startElement('image');
        
        					foreach ($array['images'] as $key => $value)
        					{ 
        						$this->writeElement($key, $value);
        					}
        					$this->endElement();
        
        
        			$this->endElement(); 
        		}
        
        

        And to set the array in my code I am doing:

        
        if(mysql_num_rows($images))
        		{
        			$item['images'] = array();
        			$image_count = 1;
        
        		while($image_row = mysql_fetch_assoc($images)) 
        
        		{
        			$item['images']['image_'.$image_count.'_seq'] = $image_row['display_order'];
        			$item['images']['image_'.$image_count.'_filename'] = $image_row['full_filename'];
        			$image_count ++;
        		}
        	}
        
        

        So I am close to what I needed but not all the way...

        Ideas, gurus?

          3 years later

          Yeah, I know this is an old topic, but I want to thank you for writing this up. Like you said, the doc pages for this are sorely lacking, which is unusual for PHP, and this little tutorial will save me a lot of time experimenting with everything. 🙂

          So yeah, thanks again!

            a year later

            I'd like just to point out that the method:

            setIndent()

            actually expects a boolean value, not an int. In the example you do:

            $writer->setIndent(4);

            which, apparently, is expected to set 4 spaces as indentation. But it actually just enables indentation (which by default is not enabled) and sets the default indentation, which is 2 spaces, that we can see in the output XML you showed. In order to actually set 4 spaces as indentation, after toggling on indentation you have to do:

            $writer->setIndent(true); // toggle indentation on
            $writer->setIndentString("    "); // set 4 spaces as indentation

            this will actually set the string we pass to that method as indentation. Kinda a "weak" method, as it allows any string to be set as indentation.

            And I also found this very old post very useful~

              Write a Reply...