RSS - PHP (4, 5) implementations

June 23, 2008 by PHP  

There is a few methods if you're planning to parse RSS in PHP, depending on your version of PHP, it can prove to be quite tedious.

If you're looking for an out of the box solution there are components available in the PEAR package and a number of open source projects, that you can easily use as well.

We're however going to code this ourselves, the following code is by no means a mature solution (it assumes a lot of things), and should soley be used as a starting point - ensure that you've got sufficient error handling.

In the first example, we're going to use the xml parser functions in PHP to populate our RSS object, we also attach three events (openElement, closeElement and cdata) that aid us in parsing the feed.

<?php

class RSSReader 
{
    var $inItem = false;
    var $inChannel = false;
    var $currentTag = "";
    var $items = array();
    var $count = 0;	
	
    function RSSReader($url) 
    {
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, "openElement", "closeElement");
        xml_set_character_data_handler($this->parser, "cdata");
        $contents = file_get_contents($url);
        xml_parse($this->parser, $contents);
        xml_parser_free($this->parser);
    }

    function openElement($parser, $tag, $attributes) 
    {
        switch($tag)
        {
            case "ITEM":				
                $this->inItem = true;
                $this->inChannel = false;
                $this->items[$this->count] = array();
                break;
            case "CHANNEL":
                $this->inChannel = true;
        }		
        $this->currentTag = strtolower($tag);
    }	

    function cdata($parser, $cdata) 
    {
        if ($this->inItem) 
        {			
            if ($this->currentTag != "item")
            {
                $this->items[$this->count][$this->currentTag].= $cdata;
            }
        }
        		
        if ($this->inChannel)
        {
            if ($this->currentTag == "image")
            {
                $this->inChannel = false;
            }
            else
            {
                $this->.= $cdata;
            }
        }
    }

    function closeElement($parser, $tag) 
    {
        if ($tag == "ITEM")
        {
            $this->count++;
            $this->inItem = false;
            $this->inChannel = false;
        }
    }
}

?>
<?php

class RSSReader 
{
    private $inItem = false;
    private $inChannel = false;
    private $currentTag = "";
    public $items = array();
    public $count = 0;	
	
    public function RSSReader($url) 
    {
        $this->parser = xml_parser_create();
        xml_set_object($this->parser, $this);
        xml_set_element_handler($this->parser, "openElement", "closeElement");
        xml_set_character_data_handler($this->parser, "cdata");
        $contents = file_get_contents($url);
        xml_parse($this->parser, $contents);
        xml_parser_free($this->parser);
    }

    private function openElement($parser, $tag, $attributes) 
    {
        switch($tag)
        {
            case "ITEM":				
                $this->inItem = true;
                $this->inChannel = false;
                $this->items[$this->count] = array();
                break;
            case "CHANNEL":
                $this->inChannel = true;
        }		
        $this->currentTag = strtolower($tag);
    }	

    private function cdata($parser, $cdata) 
    {
        if ($this->inItem) 
        {			
            if ($this->currentTag != "item")
            {
                $this->items[$this->count][$this->currentTag].= $cdata;
            }
        }
        		
        if ($this->inChannel)
        {
            if ($this->currentTag == "image")
            {
                $this->inChannel = false;
            }
            else
            {
                $this->.= $cdata;
            }
        }
    }

    private function closeElement($parser, $tag) 
    {
        if ($tag == "ITEM")
        {
            $this->count++;
            $this->inItem = false;
            $this->inChannel = false;
        }
    }
}

?>

If you're using PHP on a windows server, you can easily use com components like the Microsoft.XMLDOM - which we used in the javascript example of this article. (I only included the PHP 5 code, since I had some issues making the com object work 100% in PHP 4, will look into it sometime)

<?php

class RSSReader
{
    public $items = array();

    public function RSSReader($url)
    {
        $xmlDoc = new COM("Microsoft.XMLDOM");
        $xmlDoc->async = false;
        $xmlDoc->load($url);
        $this->title = $this->getElement($xmlDoc, 'title');
        $this->link = $this->getElement($xmlDoc, 'link');
        $this->description = $this->getElement($xmlDoc, 'description');

        $items = $xmlDoc->getElementsByTagName('item');

        for ($i = 0; $i < $items->length; $i++) 
        {
            $this->items[$i] = array('title' => $this->getElement($items[$i], 'title'),
				                        'description' => $this->getElement($items[$i], 'description'),
				                        'link' => $this->getElement($items[$i], 'link'));
        }
    }

    private function getElement($parent, $tagName)
    {
        $element = $parent->getElementsByTagName($tagName);
        return $element[0]->firstChild->nodeValue;
    }	
}

?>

Using the SimpleXml extension available in PHP 5, provides us with a very simple solution.

<?php                            

class RSSReader 
{
    public function RSSReader($url) 
    {
        $contents = file_get_contents($url); 
        $rss = new SimpleXmlElement($contents);
        $this->title = $rss->channel->title;
        $this->link = $rss->channel->link;
        $this->decription = $rss->channel->description;
        $this->date = $rss->channel->pubDate;
        $this->image = $rss->channel->image;
        $this->items = $rss->channel->item;		
    }
}

?>

Other solutions



There aren't as many friendly ways to parse RSS in PHP like there is in .net for example but the ones available are quite efficient.

Other options I can think of is that you'll be able to use is xsl(in a server side manner(like in .net), client side if you dont mind cross browser compatibility) to format the rss feed, in a windows web hosting environment you can create yourself some com/.net components, or use existing windows components, which is useable inside php.


Leave a Comment



Related Posts

RSS - C#/VB.NET implementations

June 23, 2008

RSS - JavaScript implementations

June 23, 2008


Related Downloads

How to create a RSS Reader