Building a simple RSS News Aggregator
Intro - RSS news aggregator Is built using PHP, SQLite, and simple XML Use to  - plug into RSS news feeds from all    over the web - create a newscast that reflects your    needs and interest for your website  It updates itself automatically with latest stories every time viewing it
Intro - RSS Stand for RDF Site Summary Use to publish and distribute information about what’s new and interesting on a particular site at a particular time An RSS document typically contains a list of resources (URLs), marked up with descriptive metadata.
Example of RSS document <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; xmlns=&quot;http://purl.org/rss/1.0/&quot;> <channel rdf:about=&quot;http://www.melonfire.com/&quot;>   <title>Trog</title>   <description>Well-written technical articles and tutorials on web technologies</description>   <link>http://www.melonfire.com/community/columns/trog/</link>   <items>    <rdf:Seq>     <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=100&quot; />     <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=71&quot; />
Cont’ <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=62&quot; />    </rdf:Seq>   </items> </channel> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=100&quot;>   <title>Building A PHP-Based Mail Client (part 1)</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=100</link>   <description>Ever wondered how web-based mail clients work? Find out here.</description> </item> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=71&quot;>
Cont’ <title>Using PHP With XML (part 1)</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=71</link>   <description>Use PHP's SAX parser to parse XML data and generate HTML pages.</description> </item> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=62&quot;>   <title>Access Granted</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=62</link>   <description>Precisely control access to information with the SQLite grant tables.</description> </item> </rdf:RDF>
Cont’ An RDF file is split into clearly demarcated sections First, the document prolog, namespace declarations, and root element. Follow by <channel> block which contains general information on the channel <items> block contains a sequential list  of all the resources describe within the RDF document <item> block describe a single resource in greater detail.
Design A Simple Database CREATE TABLE rss ( id INTEGER NOT NULL PRIMARY KEY, title varchar (255) NOT NULL, url varchar (255) NOT NULL, count INTEGER NOT NULL ); INSERT INTO rss VALUES (1, ‘Slashdot’, ‘http://slashdot.org/slashdot.rdf’, 5); INSERT INTO rss VALUES (2, ‘Wired News’, ‘http://www.wired.com/news_drop/netcenter/netcenter.rdf’, 5); INSERTINTO rss VALUES (3, ‘Business News’, ‘http://www.npr.org/rss/rss.php?topicId=6’, 3); INSERT INTO rss VALUES (4, ‘Health News’, ‘http://news.bbc.co.uk/rss/newsonline_world_edition/health/rss091.xml’, 3); INSERT INTO rss VALUES (5, ‘Freshmeat’, ‘http://www.freshmeat.net/backend/fm-release.rdf’, 5)
Create User.php <?php // PHP 5 // include configuration file include( 'config.php' ); // open database file $handle  =  sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' ); // generate and execute query $query  =  &quot;SELECT id, title, url, count FROM rss&quot; ; $result  =  sqlite_query ( $handle ,  $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));
Cont’ // if records present if ( sqlite_num_rows ( $result ) >  0 ) {      // iterate through resultset     // fetch and parse feed       while( $row  =  sqlite_fetch_object ( $result )) {          $xml  =  simplexml_load_file ( $row -> url );         echo  &quot;<h4>$row->title</h4>&quot; ;          // print descriptions          for ( $x  =  0 ;  $x  <  $row -> count ;  $x ++) {              // for RSS 0.91              if (isset( $xml -> channel -> item )) {                  $item  =  $xml -> channel -> item [ $x ];             }           
Cont’   // for RSS 1.0              elseif (isset( $xml -> item )) {                  $item  =  $xml -> item [ $x ];             }             echo  &quot;<a href=\&quot;$item->link\&quot;>$item->title</a><br />$item->description<p />&quot; ;         }         echo  &quot;<hr />&quot; ;          // reset variables          unset( $xml );         unset( $item );     } } // if no records present // display message
Cont’ else { ?>     <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close ( $handle ); ?>
Cont’ First is to obtain a list of RSS feeds configured by the user from the SQLite database Therefore, a SQLite database handle is initialized, and a SQL SELECT query is executed A while() loop is used to iterate through the resulting records For each obtained URL, the simplexml_load_file() function is used to retrieve and read RSS feed.  A for() loop is executed and the appropriate number of <item> elements in the feed are parsed.  The path to access an <item> differs depending on the feed is RSS 0.91 or RSS 1.0 If the database is empty, error message will appear.
config.php config.php is included at the top of every script. It contains database access parameters: <?php // database details // always use a directory that cannot be accessed from the web $path  =  $_SERVER [ 'DOCUMENT_ROOT' ]. '/../' ; $db  =  $path . 'rss.db' ; ?>
admin.php <html> <head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <h4>Current Feeds:</h4> <table border = '0' cellspacing = '10'> <?php // PHP 5 // include configuration file include( 'config.php' ); // open database file $handle  =  sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
// generate and execute query $query  =  &quot;SELECT id, title, url, count FROM rss&quot; ; $result  =  sqlite_query ( $handle ,  $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle ))); // if records present if ( sqlite_num_rows ( $result ) >  0 ) {      // iterate through result set     // print article titles      while ( $row  =  sqlite_fetch_object ( $result )) {   ?>         <tr>         <td> <?php  echo  $row -> title ;  ?>  ( <?php  echo  $row -> count ;  ?> )</td>         <td><font size = '-2'><a href=&quot;delete.php?id= <?php  echo  $row -> id ;  ?> &quot;>delete</a></font></td>         </tr> Cont’
  <?php      } } // if there are no records present, display message else { ?>     <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close ( $handle ); ?> Cont’
</table> <h4>Add New Feed:</h4> <form action = 'add.php' method = 'post'> <table border = '0' cellspacing = '5'> <tr>     <td>Title</td>     <td><input type = 'text' name = 'title'></td> </tr> <tr>     <td>Feed URL</td>     <td><input type = 'text' name = 'url'></td> </tr> <tr>     <td>Stories to display</td>     <td><input type = 'text' name = 'count' size = '2'></td> </tr> Cont’
Cont’ <tr>     <td colspan = '2' align = 'right'><input type = 'submit' name = 'submit' value = 'Add RSS Feed'></td> </tr> </table> </form> </body> </html>
Cont’ There are two section is this script: - The first half connects to the database and    prints a list of all the currently configured    news feeds with a “delete” link next to    each. - The second half contains a form for admin    to add a new feed, together with its      attributes. Once the form is submitted, the data gets POST-ed to scripts add.php which validates it and save it to the database.
add.php <html> <head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset( $_POST [ 'submit' ])) {      // check form input for errors          // check title      if ( trim ( $_POST [ 'title' ]) ==  '' ) {         die( 'ERROR: Please enter a title' );     }
Cont’   // check URL      if (( trim ( $_POST [ 'url' ]) ==  '' ) || ! ereg ( &quot;^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\._\?\,\'/\\\+&%\$#\=~\-])*$&quot; ,  $_POST [ 'url' ])) {         die( 'ERROR: Please enter a valid URL' );     }      // check story number      if (! is_numeric ( $_POST [ 'count' ])) {         die( 'ERROR: Please enter a valid story count' );     }      // include configuration file      include( 'config.php' );   // open database file      $handle  =  sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
// generate and execute query      $query  =  &quot;INSERT INTO rss (title, url, count) VALUES ('&quot; . $_POST [ 'title' ]. &quot;', '&quot; . $_POST [ 'url' ]. &quot;', '&quot; . $_POST [ 'count' ]. &quot;')&quot; ;      $result  =  sqlite_query ( $handle ,  $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));      // close connection      sqlite_close ( $handle );      // print success message      echo  &quot;Item successfully added to the database! Click <a href = 'admin.php'>here</a> to return to the main page&quot; ; } else {     die( 'ERROR: Data not correctly submitted' ); } ?> </body> Cont’
Cont’ There are three tests in the script to ensure the data being saved doesn’t contain gibberish One checks for the presence of a descriptive title Another uses the is_numeric() function to verify that the value entered for the story count is a valid number The third uses the ereg() function to check the format of the URL.
delete.php <html> <head><basefont face = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset( $_GET [ 'id' ]) &&  is_numeric ( $_GET [ 'id' ])) {      // include configuration file      include( 'config.php' );           // open database file      $handle  =  sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
// generate and execute query      $query  =  &quot;DELETE FROM rss WHERE id = '&quot; . $_GET [ 'id' ]. &quot;'&quot; ;      $result  =  sqlite_query ( $handle ,  $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));           // close connection      sqlite_close ( $handle );      // print success message      echo  &quot;Item successfully removed from the database! Click <a href = 'admin.php'>here</a> to return to the main page&quot; ; } else {     die( 'ERROR: Data not correctly submitted' ); } ?> </body> </html>   Cont’
Cont’ The record ID passed through the URL GET method is retrieved by delete.php A DELETE SQL query is used is delete.php to erase the corresponding record.

Php Rss

  • 1.
    Building a simpleRSS News Aggregator
  • 2.
    Intro - RSSnews aggregator Is built using PHP, SQLite, and simple XML Use to - plug into RSS news feeds from all over the web - create a newscast that reflects your needs and interest for your website It updates itself automatically with latest stories every time viewing it
  • 3.
    Intro - RSSStand for RDF Site Summary Use to publish and distribute information about what’s new and interesting on a particular site at a particular time An RSS document typically contains a list of resources (URLs), marked up with descriptive metadata.
  • 4.
    Example of RSSdocument <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <rdf:RDF xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; xmlns=&quot;http://purl.org/rss/1.0/&quot;> <channel rdf:about=&quot;http://www.melonfire.com/&quot;>   <title>Trog</title>   <description>Well-written technical articles and tutorials on web technologies</description>   <link>http://www.melonfire.com/community/columns/trog/</link>   <items>    <rdf:Seq>     <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=100&quot; />     <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=71&quot; />
  • 5.
    Cont’ <li rdf:resource=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=62&quot;/>    </rdf:Seq>   </items> </channel> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=100&quot;>   <title>Building A PHP-Based Mail Client (part 1)</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=100</link>   <description>Ever wondered how web-based mail clients work? Find out here.</description> </item> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=71&quot;>
  • 6.
    Cont’ <title>Using PHPWith XML (part 1)</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=71</link>   <description>Use PHP's SAX parser to parse XML data and generate HTML pages.</description> </item> <item rdf:about=&quot;http://www.melonfire.com/community/columns/trog/article.php?id=62&quot;>   <title>Access Granted</title>   <link>http://www.melonfire.com/community/columns/trog/article.php?id=62</link>   <description>Precisely control access to information with the SQLite grant tables.</description> </item> </rdf:RDF>
  • 7.
    Cont’ An RDFfile is split into clearly demarcated sections First, the document prolog, namespace declarations, and root element. Follow by <channel> block which contains general information on the channel <items> block contains a sequential list of all the resources describe within the RDF document <item> block describe a single resource in greater detail.
  • 8.
    Design A SimpleDatabase CREATE TABLE rss ( id INTEGER NOT NULL PRIMARY KEY, title varchar (255) NOT NULL, url varchar (255) NOT NULL, count INTEGER NOT NULL ); INSERT INTO rss VALUES (1, ‘Slashdot’, ‘http://slashdot.org/slashdot.rdf’, 5); INSERT INTO rss VALUES (2, ‘Wired News’, ‘http://www.wired.com/news_drop/netcenter/netcenter.rdf’, 5); INSERTINTO rss VALUES (3, ‘Business News’, ‘http://www.npr.org/rss/rss.php?topicId=6’, 3); INSERT INTO rss VALUES (4, ‘Health News’, ‘http://news.bbc.co.uk/rss/newsonline_world_edition/health/rss091.xml’, 3); INSERT INTO rss VALUES (5, ‘Freshmeat’, ‘http://www.freshmeat.net/backend/fm-release.rdf’, 5)
  • 9.
    Create User.php <?php// PHP 5 // include configuration file include( 'config.php' ); // open database file $handle = sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' ); // generate and execute query $query = &quot;SELECT id, title, url, count FROM rss&quot; ; $result = sqlite_query ( $handle , $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));
  • 10.
    Cont’ // ifrecords present if ( sqlite_num_rows ( $result ) > 0 ) {      // iterate through resultset     // fetch and parse feed      while( $row = sqlite_fetch_object ( $result )) {          $xml = simplexml_load_file ( $row -> url );         echo &quot;<h4>$row->title</h4>&quot; ;          // print descriptions          for ( $x = 0 ; $x < $row -> count ; $x ++) {              // for RSS 0.91              if (isset( $xml -> channel -> item )) {                  $item = $xml -> channel -> item [ $x ];             }           
  • 11.
    Cont’   //for RSS 1.0              elseif (isset( $xml -> item )) {                  $item = $xml -> item [ $x ];             }             echo &quot;<a href=\&quot;$item->link\&quot;>$item->title</a><br />$item->description<p />&quot; ;         }         echo &quot;<hr />&quot; ;          // reset variables          unset( $xml );         unset( $item );     } } // if no records present // display message
  • 12.
    Cont’ else {?>     <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close ( $handle ); ?>
  • 13.
    Cont’ First isto obtain a list of RSS feeds configured by the user from the SQLite database Therefore, a SQLite database handle is initialized, and a SQL SELECT query is executed A while() loop is used to iterate through the resulting records For each obtained URL, the simplexml_load_file() function is used to retrieve and read RSS feed. A for() loop is executed and the appropriate number of <item> elements in the feed are parsed. The path to access an <item> differs depending on the feed is RSS 0.91 or RSS 1.0 If the database is empty, error message will appear.
  • 14.
    config.php config.php isincluded at the top of every script. It contains database access parameters: <?php // database details // always use a directory that cannot be accessed from the web $path = $_SERVER [ 'DOCUMENT_ROOT' ]. '/../' ; $db = $path . 'rss.db' ; ?>
  • 15.
    admin.php <html> <head><basefontface = 'Arial'></head> <body> <h2>Feed Manager</h2> <h4>Current Feeds:</h4> <table border = '0' cellspacing = '10'> <?php // PHP 5 // include configuration file include( 'config.php' ); // open database file $handle = sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
  • 16.
    // generate andexecute query $query = &quot;SELECT id, title, url, count FROM rss&quot; ; $result = sqlite_query ( $handle , $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle ))); // if records present if ( sqlite_num_rows ( $result ) > 0 ) {      // iterate through result set     // print article titles      while ( $row = sqlite_fetch_object ( $result )) {   ?>         <tr>         <td> <?php echo $row -> title ; ?> ( <?php echo $row -> count ; ?> )</td>         <td><font size = '-2'><a href=&quot;delete.php?id= <?php echo $row -> id ; ?> &quot;>delete</a></font></td>         </tr> Cont’
  • 17.
      <?php     } } // if there are no records present, display message else { ?>     <font size = '-1'>No feeds currently configured</font> <?php } // close connection sqlite_close ( $handle ); ?> Cont’
  • 18.
    </table> <h4>Add NewFeed:</h4> <form action = 'add.php' method = 'post'> <table border = '0' cellspacing = '5'> <tr>     <td>Title</td>     <td><input type = 'text' name = 'title'></td> </tr> <tr>     <td>Feed URL</td>     <td><input type = 'text' name = 'url'></td> </tr> <tr>     <td>Stories to display</td>     <td><input type = 'text' name = 'count' size = '2'></td> </tr> Cont’
  • 19.
    Cont’ <tr>     <tdcolspan = '2' align = 'right'><input type = 'submit' name = 'submit' value = 'Add RSS Feed'></td> </tr> </table> </form> </body> </html>
  • 20.
    Cont’ There aretwo section is this script: - The first half connects to the database and prints a list of all the currently configured news feeds with a “delete” link next to each. - The second half contains a form for admin to add a new feed, together with its attributes. Once the form is submitted, the data gets POST-ed to scripts add.php which validates it and save it to the database.
  • 21.
    add.php <html> <head><basefontface = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset( $_POST [ 'submit' ])) {      // check form input for errors          // check title      if ( trim ( $_POST [ 'title' ]) == '' ) {         die( 'ERROR: Please enter a title' );     }
  • 22.
    Cont’   //check URL      if (( trim ( $_POST [ 'url' ]) == '' ) || ! ereg ( &quot;^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\._\?\,\'/\\\+&%\$#\=~\-])*$&quot; , $_POST [ 'url' ])) {         die( 'ERROR: Please enter a valid URL' );     }      // check story number      if (! is_numeric ( $_POST [ 'count' ])) {         die( 'ERROR: Please enter a valid story count' );     }      // include configuration file      include( 'config.php' ); // open database file      $handle = sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
  • 23.
    // generate andexecute query      $query = &quot;INSERT INTO rss (title, url, count) VALUES ('&quot; . $_POST [ 'title' ]. &quot;', '&quot; . $_POST [ 'url' ]. &quot;', '&quot; . $_POST [ 'count' ]. &quot;')&quot; ;      $result = sqlite_query ( $handle , $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));      // close connection      sqlite_close ( $handle );      // print success message      echo &quot;Item successfully added to the database! Click <a href = 'admin.php'>here</a> to return to the main page&quot; ; } else {     die( 'ERROR: Data not correctly submitted' ); } ?> </body> Cont’
  • 24.
    Cont’ There arethree tests in the script to ensure the data being saved doesn’t contain gibberish One checks for the presence of a descriptive title Another uses the is_numeric() function to verify that the value entered for the story count is a valid number The third uses the ereg() function to check the format of the URL.
  • 25.
    delete.php <html> <head><basefontface = 'Arial'></head> <body> <h2>Feed Manager</h2> <?php // PHP 5 if (isset( $_GET [ 'id' ]) && is_numeric ( $_GET [ 'id' ])) {      // include configuration file      include( 'config.php' );           // open database file      $handle = sqlite_open ( $db ) or die( 'ERROR: Unable to open database!' );
  • 26.
    // generate andexecute query      $query = &quot;DELETE FROM rss WHERE id = '&quot; . $_GET [ 'id' ]. &quot;'&quot; ;      $result = sqlite_query ( $handle , $query ) or die( &quot;ERROR: $query. &quot; . sqlite_error_string ( sqlite_last_error ( $handle )));           // close connection      sqlite_close ( $handle );      // print success message      echo &quot;Item successfully removed from the database! Click <a href = 'admin.php'>here</a> to return to the main page&quot; ; } else {     die( 'ERROR: Data not correctly submitted' ); } ?> </body> </html> Cont’
  • 27.
    Cont’ The recordID passed through the URL GET method is retrieved by delete.php A DELETE SQL query is used is delete.php to erase the corresponding record.