Table of Contents

RSS - Combine multiple RSS Feeds

This script will allow you to add RSS feeds from multiple sites and integrate them into yours dynamically.

<?php
// simple timeout in seconds
$timeout = 2;
 
// variable to be used later
$xml_string = "";
 
// let's open the socket to the RSS feed
$fp = @fsockopen("feeds.warhammeronline.com", 80, $errno, $errstr, $timeout);
 
// check to see if the fsockopen returned a valid resource
if ($fp) {
    // now that we have a valid resource, let's request the data that we need
    fwrite($fp, "GET /warherald/RSSFeed.war?type=current HTTP/1.0\r\n");
    fwrite($fp, "Host: feeds.warhammeronline.com\r\n");
    fwrite($fp, "Connection: Close\r\n\r\n");
 
    // let's wait until data becomes available within the stream
    stream_set_blocking($fp, TRUE);
 
    // but let's only wait for a specific amount of time
    stream_set_timeout($fp,$timeout);
 
    // get the header/meta data to use, currently we are just using this to see if we timeout or not
    $info = stream_get_meta_data($fp);
 
    // while there is still data in the stream and we haven't timedout, then get the next bit of data
    while ((!feof($fp)) && (!$info['timed_out'])) {
 
        // get the next line in the stream
        $xml_string .= fgets($fp, 4096);
 
        // get the header/meta data to use, currently we are just using this to see if we timeout or not
        $info = stream_get_meta_data($fp);
 
        // this isn't required, but I like to send the data to the browser as soon as possible
        ob_flush;
        flush();
    }
 
    // we are done with the stream, so get rid of it
    fclose($fp);
}
 
// we timed out, so let the user know, if you want
if ($info['timed_out']) {
    echo "Warhammer News feed - Connection timed out";
} else {
    // we need to strip off the initial part of the stream that we don't need, we just want the XML from the RSS feed
    $xml_string = substr($xml_string, strpos($xml_string, '<'));
 
    // we are using the built in php function to parse the xml
    // and convert it into an object we can use
    $xml = simplexml_load_string($xml_string);
 
    // check to see if the object was created from the RSS feed
    if (!is_object($xml)) {
        echo "Warhammer News feed - Error converting xml";
    } else {
        // this section, is a bit hardcoded for this particular RSS feed,
        // but basically, you just walk the XML tree as an object
 
        // here we are looping through all the children of this particular parent
        foreach($xml->channel->item as $key) {
            // variable to use later
            $temp_title = $key->title;
            $link = $key->link;
 
            // I don't always have enough room on the page to show the
            // entire title of the RSS feed, so I am just limiting it here
            // and then adding 3 dots (...) to show that the title is longer than displayed
            $title = str_replace('-', '', substr($key->title, 0, 25)) . "...";
 
            // display it to the page, even though the text of the link will be
            // limited to a specific number of characters
            // when you roll over it with your mouse, it will show the full title
            // in the little popup that is built into the href tag
            echo "<li><a href='$link' target='_blank' title='$temp_title'>$title</a></li>";
        }
    }
 
    // we are done, so get rid of it
    $xml = NULL;
}

Another way

<?php
class Feed_Amalgamator
{
    public $urls = array();
    public $data = array();
 
    public function addFeeds( array $feeds )
    {
        $this->urls = array_merge( $this->urls, array_values($feeds) );
    }
 
    public function grabRss()
    {
        foreach ( $this->urls as $feed )
        {
            $data = @new SimpleXMLElement( $feed, 0, true );
            if ( !$data )
                throw new Exception( 'Could not load: ' . $feed );
            foreach ( $data->channel->item as $item )
            {
                $this->data[] = $item;
            }
        }
    }
 
    public function amalgamate()
    {
        shuffle( $this->data );
        $temp = array();
        foreach ( $this->data as $item )
        {
            if ( !in_array($item->link, $this->links($temp)) )
            {
                $temp[] = $item;
            }
        }
        $this->data = $temp;
        shuffle( $this->data );
    }
 
    private function links( array $items )
    {
        $links = array();
        foreach ( $items as $item )
        {
            $links[] = $item->link;
        }
        return $links;
    }
}
 
/********* Example *********/
 
$urls = array( 'http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/teams/m/man_city/rss.xml', 'http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/teams/l/liverpool/rss.xml' );
 
try
{
    $feeds = new Feed_Amalgamator;
    $feeds->addFeeds( $urls );
    $feeds->grabRss();
    $feeds->amalgamate();
}
catch ( exception $e )
{
    die( $e->getMessage() );
}
 
foreach ( $feeds->data as $item ) :
extract( (array) $item );
?>
<h2><a href="<?php echo $link; ?>"><?php echo $title; ?></a></h2>
<p><?php echo $description; ?></p>
<p><em><?php echo $pubDate; ?></em></p>
<?php endforeach; ?>

Another Way

<?php
 
// Set the feed URLs here
$feeds = array(
    //'http://www.example.org/feed1.rss',
    //'http://www.example.org/feed2.rss',
 
    'http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/teams/m/man_city/rss.xml',
    'http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/teams/l/liverpool/rss.xml',
    // etc.
);
 
 
// Get all feed entries
$entries = array();
foreach ($feeds as $feed) {
    $xml = simplexml_load_file($feed);
    $entries = array_merge($entries, $xml->xpath('/rss//item'));
}
 
// Sort feed entries by pubDate (ascending)
usort($entries, function ($x, $y) {
    //return strtotime($x->pubDate) - strtotime($y->pubDate);
    return strtotime($y->pubDate) - strtotime($x->pubDate);
});
 
print_r($entries);
?>

Another way

With 4 lines, I import a rss to an array.

$feed = implode(file('http://yourdomains.com/feed.rss'));
$xml = simplexml_load_string($feed);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

Try also changing 1st line for one of these…

$feed = file_get_contents('http://yourdomains.com/feed.rss');
$feed = json_decode(json_encode(simplexml_load_file('news.google.com‌​/?output=rss')), true); 

For a more complex solution

$feed = new DOMDocument();
 $feed->load('file.rss');
 $json = array();
 $json['title'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
 $json['description'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
 $json['link'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('link')->item(0)->firstChild->nodeValue;
 $items = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('item');
 
 $json['item'] = array();
 $i = 0;
 
 foreach($items as $key => $item) {
 $title = $item->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
 $description = $item->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
 $pubDate = $item->getElementsByTagName('pubDate')->item(0)->firstChild->nodeValue;
 $guid = $item->getElementsByTagName('guid')->item(0)->firstChild->nodeValue;
 
 $json['item'][$key]['title'] = $title;
 $json['item'][$key]['description'] = $description;
 $json['item'][$key]['pubdate'] = $pubDate;
 $json['item'][$key]['guid'] = $guid; 
 }
 
echo json_encode($json);