Creare un feed RSS in PHP

Matteo - 25 Maggio 2005

Presento il semplice script PHP per la generazione dei feed RSS (versione 2.0) di questo sito, opportunamente commentato:

<?
    // specifica il tipo di documento. NECESSARIO per far 
    // interpretare il documento generato come un feed xml,
    // nonostante l'estensione PHP
    header('Content-Type: application/xml');
    // specifica la versione di XML, l'encoding e la versione
    // del formato RSS adottato. L'encoding impostato e' quello
    // windows, anche se non dovrebbe servire.
    print("<?xml version="1.0" encoding="ISO-8859-1" ?>n");
    print("<rss version="2.0" ".
        "xmlns="http://backend.userland.com/rss2">n");
    // funzione per eliminare dal testo i tag html e sostituire
    // gli a capo in stile mac, windows e unix in spazi
    function StripHTML($str)
    {
        $str = strip_tags($str);
        return str_replace(array(chr(13).chr(10), 
            chr(10).chr(13), chr(13), chr(10)), ' ', $str);
    }
    // tratta da un commento su php.net alla funzione htmlentities.
    // Sostituisce tutti i caratteri non validi per l'xml in entita',
    // evitando l'uso di entita' "con nome" che sono valide in html,
    // ma non per un parser validante xml. L'unica entita' considerata
    // valida da un parser xml normalmente e' &.
    function xmlentities($string, $quote_style=ENT_COMPAT)
    {
        // elimina preliminarmente tutte le entita' riconvertendole
        // in caratteri. In questo modo si evita una eventuale doppia 
        // conversione delle entita'. Usa questo metodo anziche' un 
        // semplice html_entity_decode per funzionare anche su sistemi 
        // php meno recenti.
        $trans = get_html_translation_table(
            HTML_ENTITIES, $quote_style);
        $trans = array_flip($trans);
        $string = strtr($string, $trans);
        // elimina le entita' di tipo numerico
            // decimali
        $string = preg_replace(
                '/&#(d+);/me',"chr(\1)", $string);
            // esadecimali
        $string = preg_replace(
                '/&#x([a-f0-9]+);/mei',"chr(0x\1)", $string);
        $trans = get_html_translation_table(
            HTML_ENTITIES, $quote_style);
        foreach ($trans as $key => $value)
            $trans[$key] = '&#'.ord($key).';';
        return strtr($string, $trans);
    }
    // ottiene il link di base al sito
    $baseLink = "http://".$_SERVER['SERVER_NAME'].
        dirname($_SERVER['PHP_SELF']).'/';
    // determina il feed da generare
    $type = "weblog";
    if(isset($_GET['f']))
        $type = $_GET['f'];
    // se il feed da generare non e' riconosciuto, esce
    if($type != "weblog" && $type != "koan")
    {
        print("</rss>");
        exit;
    }
    // imposta le variabili in base al feed da generare
    if($type == "weblog")
    {
        $feedName = "Weblog";
        $baseLink .= "index.php";
        $newsTable = "weblog";
        $addComments = true;
    }
    else if($type == "koan")
    {
        $feedName = "Koan";
        $baseLink .= "koan.php";
        $newsTable = "koan";
        $addComments = false;
    }
    /*
       aggiunge informazioni standard per il feed:
       titolo del feed, link al sito di riferimento,
       descrizione del feed, lingua utilizzata,
       link alla specifica dell'rss,
       nome del generatore e tempo di validita' delle
       informazioni acquisite (consiglia al feed reader
       ogni quanti minuti aggiornare il feed).
       Altre informazioni utili possono essere il managingEditor
       ed il webMaster, ovvero gli indirizzi email di chi produce
       il feed e di chi lo mantiene il sito.
    */
?>
   <channel>
      <title>DigitalWaters.net - <?=$feedName?></title>
      <link><?=$baseLink?></link>
      <description>
            <?=$feedName?> di Juna, Matteo e Marco
      </description>
      <language>it</language>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs>
      <generator>PHP by Matteo</generator>
      <ttl>120</ttl>
<?
    // inclusione delle funzioni per l'accesso al db
    require_once("db.inc.php");
    // apre una connessione col db
    $db = opendb();
    // variabili per le tablature nei print
    $pfx1 = "      ";
    $pfx2 = "          ";
    // crea il link di base per le notizie. Notare
    // l'& anche nel link per evitare che l'ampersand
    // sia considerato dal parser xml l'inizio di una entita'!
    $baseNewsLink = $baseLink."?action=show&amp;id=";
    // query verso il db per ottenere id, titolo, testo e nome
    // dell'autore delle prime 7 notizie del feed da generare
    $query_handler = mysql_query(
        "SELECT w.id, w.titolo_ita, w.testo_ita, u.nome ".
        "FROM ".$newsTable." w, utenti u WHERE u.id=w.autore ".
        "ORDER BY w.data DESC LIMIT 7");
    while ($row = mysql_fetch_array($query_handler))
    {
        $newsId = $row['id'];
        // i caratteri non validi nel titolo vengono convertiti
        $titolo = xmlentities(stripslashes($row['titolo_ita']));
        // i caratteri non validi nel testo vengono convertiti
        // dopo aver tolto tutti i tag ed aver tagliato 
        // il testo a 150 caratteri
        $testo  = StripHTML(stripslashes($row['testo_ita']));
        if(strlen($testo) > 150)
            $testo = substr($testo, 0, 150)."...";
        $testo = xmlentities($testo);
        // vengono inseriti solo i primi 3 caratteri del nome
        $autore = substr($row['nome'], 0, 3);
        // tag ITEM
        print($pfx1."<item>n");
        // tag TITLE
        print($pfx2."<title>[".$autore."] ".$titolo);
        if($addComments)
        {
            // aggiunge l'eventuale numero di commenti leggendolo
            // dal database
            $count_query = mysql_query("SELECT COUNT(id) ".
                "FROM commenti WHERE newsId=".$newsId);
            $comments = mysql_result($count_query, 0);
            if($comments == 1)
                print(" (1 commento)");
            else if ($comments > 1)
                print(" (".$comments." commenti)");
        }
        print("</title>n");
        // tag LINK alla pagina della notizia
        print($pfx2."<link>".$baseNewsLink.$newsId."</link>n");
        // tag DESCRIPTION con parte del testo della notizia
        print($pfx2."<description>".$testo."</description>n");
        // fine ITEM
        print($pfx1."</item>n");
    }
    // chiusura della connessione al db
    closedb($db);
    // fine del feed RSS
?>
   </channel>
</rss>

Per utilizzare uno script del genere, supponendo sia salvato in un file rss.php della root del sito, è sufficiente inserire nella sezione HEAD della pagina html di indice una dicitura del tipo:

    <link rel="alternate" type="application/rss+xml" 
        title="DW.net Weblog" href="rss.php"/>
    <link rel="alternate" type="application/rss+xml" 
        title="DW.net Koan" href="rss.php?f=koan"/>

Notare che qui vengono definiti due feed: uno per il weblog ed uno per i koan, pur utilizzando lo stesso script.

Weblog Koan Progetti Foto Contatti