[PHP] Document Object Model e leggere un RSS non è mai stato tanto facile

php ad davidonzo.comFinalmente il team di sviluppo del PHP ha deciso un serio improve delle funzionalità legate al Document Object Model. E’ quindi possibile processare file XML rapidamente e senza quintalate di codice assurdo.

In realtà nelle pagine di questo blog si era già visto qualche uso della classe DOMDocument. Ma vediamo oggi uno dei metodi che più potrebbero esservi utile: leggere il contenuto di un feed RSS e darne un output in HTML.

Via subito di codice

  $url="http://www.davidonzo.com/rss/";
  $doc = new DOMDocument;
   if(!is_file(‘rss.xml’) OR (is_file(‘rss.xml’) && (time() > filemtime(‘rss.xml’)+28800))){
    $doc->formatOutput = true;
    $doc->load($url);
    $doc->save(‘rss.xml’);
   }

  $doc->load(‘rss.xml’);
  $xpath = new DOMXPath($doc);
?>
<ul>
<?php
  $nodo = $xpath->query(‘//rss/channel/item’);
    $a = 0;
    foreach ($nodo as $nodo){
       $title = $nodo->getElementsByTagName(‘title’)->item(0)->nodeValue;
       $link =  $nodo->getElementsByTagName(‘link’)->item(0)->nodeValue;
       echo "<li><a href=\"".$link."\" target=\"_blank\">".$title."</a></li>\n";
  }
?>
</ul>

Ora una semplice spiegazione. Per prima cosa (non obbligatoria) io ho deciso di salvare il file XML remoto sul mio server, quindi controllo che già ci sia o che sia scaduto. In questo modo mi creo un micro sistema di cache che mi permette di non appesantire troppo la chiamata ad una pagina remota.

Se il file non esiste o se questo è scaduto (in funzione dei parametri che ho deciso), allora lo riscarico e salvo sul server. E’ ovvio che per fare ciò la directory di salvataggio deve essere server writable.

A questo punto per processare il file uso l’oggetto DOMXPath. Il suo costruttore inizializza la funzione query, che posso quindi usare subito per processare il file XML.

Soffermiamoci sull’argomento di $xpath->query. Con //rss/channel/item vado a processare direttamente la parte di alberto XML che mi interessa. Il doppio // non traga in inganno, in quanto è solo una rappresentazione formale del file RSS in questione, dove il primo / sta ad indicare la root (il nodo primario) del file, mentre è /rss l’elemento immediatamente successivo. Si faccia per tanto attenzione a leggere nel modo corretto l’argomento della funzione al fine di poterla riscrivere adeguatamente per ogni altri tipo di albero XML.

Una volta processata la parte di albero che ci interessa, il magico getElementsByTagName() andremo a prenderci tutti i valori che ci interessano.

7 thoughts on “[PHP] Document Object Model e leggere un RSS non è mai stato tanto facile”

  1. Mmm…
    Se il file rss.xml è presente…e anche se il sito è diverso…il file non viene sovrascritto…se lo elimino, funziona correttamente ๐Ÿ˜€

    Poi alcuni feed di feedburner provocano sempre o quasi degli errori e non solo con il tuo script ๐Ÿ™

  2. Il file rss.xml viene sovrascritto solo se è più vecchio del limite di cache gestibile.
    Se anche a scadenza non viene sovrascritto, prova a controllare i permessi del file.

    Per feedburner che errori ti da? Io ne indicizzo un paio di FB in questo modo e non ho avuto problemi.

  3. Su una decina di blog che seguo tramite feed, gestiti da feedburner, 3 mi producono pagina bianca con qualsiasi script io decida di usare per parsare l'xml

  4. Quello di Gianni è un feed atom, non RSS ๐Ÿ™‚
    Usa questo:

    <?php
    $url="http://feeds.feedburner.com/gianniamato";
    $doc = new DOMDocument;
    if(!is_file('rss.xml') OR (is_file('rss.xml') && (time() > filemtime('rss.xml')+28800))){
    $doc->formatOutput = true;
    $doc->load($url);
    $doc->save('rss.xml');
    }

    $doc->load('rss.xml');
    $xpath = new DOMXPath($doc);
    $xpath->registerNameSpace('atom', 'http://www.w3.org/2005/Atom');

    ?>
    <ul>
    <?php
    $nodo = $xpath->query('//atom:entry');
    $a = 0;
    foreach ($nodo as $nodo){
    $title = $nodo->getElementsByTagName('title')->item(0)->nodeValue;
    $link = $nodo->getElementsByTagName('link')->item(0)->nodeValue;
    echo "<li><a href="".$link."" target="_blank">".$title."</a></li>
    ";
    }
    ?>
    </ul>

    PS: il file di cache è valido 8 ore, aggiusta il valore 28800 per modificarlo.

  5. Mi intrometto ๐Ÿ™‚ Non sono praticissimo di php ma trovo molto utile questo script, e avrei una domanda: se volessi mostrare solo gli ultimi 5 post del feed?

Comments are closed.