Come avrete già capito dall'articolo precedente di Fabio Sutto o dagli altri articoli pubblicati su PRO.HTML.it (in particolare Introduzione a RSS) il formato RSS è uno "standard" per la diffusione di sommari di news, ma che con il tempo si è diviso in due versioni incompatibili tra loro. In questo articolo tratteremo la creazione di RSS versione 2.0. I feed RSS disponibili su HTML.it (tuttora in versione di sviluppo) li trovate alla pagina https://www.html.it/rss/.
Che cos'è un file RSS
Un file RSS è un semplice file xml, che a sua volta non è altro che un file ascii che segue delle precise linee guida. Essendo un semplice file ascii, in PHP possiamo creare un file RSS (ma anche un file xml) in diverse maniere: la più semplice delle quali è attraverso le funzioni di stampa dell'output (print, echo).
Inoltre per la sua natura possiamo scegliere se creare il file RSS:
- Automaticamente una volta per notte (attraverso un crontab)
- All'inserimento di ogni nuova news
- Lanciando uno script php in modo che il feed RSS venga creato ogni volta
Inutile dire che l'ultima delle opzioni è la più dispendiosa.
Un file RSS versione 2 segue le linee guida definite da Dave Winer per il Berkman Center for Internet & Society. Per sua natura è un file dalla sintassi molto semplice (a differenza della versione 1 che predilige un gran numero di funzionalità e di espansioni alla semplicità).
La creazione
Un feed RSS, come accennavo precedentemente, può essere creato in diverse maniere:
- Classi di aiuto per la scrittura di documenti xml
- Scrittura del documento linea per linea con funzioni di stampa
- Utilizzo di una classe appositamente scritta per questo scopo
La via che mi sembrava più semplice da seguire era la terza. Ho trovato una classe disponibile su phpclasses.org per la creazione di feed RSS versione 1.0, ma niente per la versione che volevo trattare. Ho deciso di svilupparne una abbastanza semplice ma facilmente espandibile. La trovate nella prossima pagina.
La classe
<?php
class MakeRSS
{
var $Articles = array();
// Channel info
var $title = '';
var $link = '';
var $description = '';
var $optional = array();
var $image = array('url' => '', 'title' => '', 'link' => '', 'description' => '', 'w' => 0, 'h' => 0);
function MakeRSS($title, $link, $description, $optional = '')
{
$this->title = $title;
$this->link = $link;
$this->description = $description;
if( is_array($optional) and count($optional) ){
$this->optional = $optional;
}
}
function AddOptional($key, $value)
{
$this->optional[$key] = $value;
}
function AddImage($title, $url, $link, $description = '')
{
$this->image['title'] = $title;
$this->image['url'] = $url;
$this->image['link'] = $link;
$this->image['description'] = $description;
if( $tmp = @getimagesize($url) ){
$this->image['w'] = ($tmp[0] > 144) ? 144 : $tmp[0];
$this->image['h'] = ($tmp[1] > 400) ? 400 : $tmp[1];
}
}
function AddArticle($title, $link, $description, $author, $optional = '')
{
// inserisce un nuovo articolo
$i = array_push($this->Articles, array('title' => $title, 'link' => $link, 'description' => $description, 'author' => $author));
// aggiunge le coppie chiave valore opzionali
// all'articolo appena inserito
if( is_array($optional) and count($optional) )
{
--$i;
while( list($k, $v) = each($optional) ){
$this->Articles[$i][$k] = $v;
}
}
}
function Output($save = false, $path = '')
{
$out = '<?xml version="1.0"?>' . "n" .
'<rss version="2.0">' . "n" .
'<channel>' . "n";
$out .= "<title>$this->title</title>n" .
"<link>$this->link</link>n" .
"<description>$this->description</description>n";
// Channel optionals
if( is_array($this->optional) and count($this->optional) )
{
while( list($k, $v) = each($this->optional) ){
$out .= "<$k>$v</$k>n";
}
}
// Image
if( $this->image['title'] and $this->image['url'] and $this->image['link'] )
{
$out .= "<image>n" .
"<title>>" . $this->image['title'] . "</title>n" .
"<url>" . $this->image['url'] . "</url>n" .
"<link>" . $this->image['link'] . "</link>n";
if( $this->image['description'] ) {
$out .= "<description>" . $this->image['description'] . "</description>n";
}
if( $this->image['w'] and $this->image['h'] ) {
$out .= "<width>" . $this->image['w'] . "</width>n" .
"<height>" . $this->image['h'] . "</height>n";
}
$out .= "</image>n";
}
// per ogni item stampa tutte le coppie chiave valore
for( $i = 0, $c = count($this->Articles); $i < $c; $i++ ){
$out .= "<item>n";
while(list($k, $v) = each($this->Articles[$i]))
{
$out .= "<".$k.">".$v."</".$k.">n";
}
$out .= "</item>n";
}
$out .= "</channel>n</rss>";
// True output
if( !$save or !$path ){
header("Content-type: application/xml");
echo $out;
return true;
}
else
{
$fh = fopen($path, 'w');
if($fh) {
fwrite($fh, $out);
fclose($fh);
return true;
}
return false;
}
}
}
?>
Esaminiamone in dettaglio le funzionalità.
Funzionalità
Attraverso questa classe è possibile creare in maniera semplice ed intuitiva un feed RSS inserendo i parametri obbligatori o comunque più utili. Ho lasciato comunque la possibilità di aggiungere manualmente alcuni parametri facoltativi in modo da poter creare un feed completo. Vengono gestiti direttamente i principali parametri delle radici channel, image e item. È possibile salvare il documento generato sul filesystem oppure inviarlo in output al client HTTP.
Funzionamento
Per prima cosa includiamo il file con la classe attraverso la funzione include:
include('file.della.classe.php');
Inizializziamo la classe passando i parametri fondamentali:
$r = new MakeRSS($titolo_del_canale, $link_al_sito_generatore, $descrizione_del_canale);
Volendo è possibile passare come quarto parametro un array associativo (chiave, valore) dove la chiave è il nome dell'oggetto da aggiungere e il valore è ciò che verrà assegnato all'oggetto (Es <chiave>valore</chiave>)
È possibile anche inserire questi parametri aggiuntivi in un secondo momento con la funzione AddOptional()
$r->AddOptional($chiave, $valore);
Ora possiamo aggiungere l'immagine che contraddistingue il canale:
$r->AddImage($titolo, $url, $link, $descrizione_facoltativa);
N.b. Le dimensioni dell'immagine vengono ricavate automaticamente attraverso la funzione getimagesize() dove possibile.
In maniera molto simile possiamo aggiungere gli articoli:
$r->AddArticle($titolo, $link, $descrizione, $autore, $parametri_opzionali);
N.b. I parametri opzionali hanno la stessa funzionalità di quelli del canale (array associativo chiave/valore)
E infine generare l'output sul disco o al volo al client HTTP:
$r->Output($salva_su_disco = false, $path_in_cui_salvare = '');
Per salvare sul disco utilizzare la funzione come di seguito:
$r->Output(true, './rss.xml');
Per mandare direttamente in output invece è possibile richiamare la funzione senza parametri:
$r->Output();
L'output
Ad esempio attraverso queste 7 righe di codice:
include('./class.rss.php');
$r = new MakeRSS('Feed RSS di freephp.html.it', 'http://freephp.html.it', 'News riguardanti il mondo del php');
$r->AddArticle('Articolo 1', 'http://freephp.html.it/articoli_falsi.php?id=1', 'Ottimo articolo 1', 'Freephp.html.it');
$r->AddArticle('Articolo 2', 'http://freephp.html.it/articoli_falsi.php?id=2', 'Ottimo articolo 2', 'Freephp.html.it');
$r->AddArticle('Articolo 3', 'http://freephp.html.it/articoli_falsi.php?id=3', 'Ottimo articolo 3', 'Freephp.html.it');
$r->AddArticle('Articolo 4', 'http://freephp.html.it/articoli_falsi.php?id=4', 'Ottimo articolo 4', 'Freephp.html.it');
$r->Output();
viene creato un feed RSS completo del genere:
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Feed RSS di freephp.html.it</title>
<link>http://freephp.html.it</link>
<description>News riguardanti il mondo del php</description>
<item>
<title>Articolo 1</title>
<link>http://freephp.html.it/articoli_falsi.php?id=1</link>
<description>Ottimo articolo 1</description>
<author>Freephp.html.it</author>
</item>
<item>
<title>Articolo 2</title>
<link>http://freephp.html.it/articoli_falsi.php?id=2</link>
<description>Ottimo articolo 2</description>
<author>Freephp.html.it</author>
</item>
<item>
<title>Articolo 3</title>
<link>http://freephp.html.it/articoli_falsi.php?id=3</link>
<description>Ottimo articolo 3</description>
<author>Freephp.html.it</author>
</item>
<item>
<title>Articolo 4</title>
<link>http://freephp.html.it/articoli_falsi.php?id=4</link>
<description>Ottimo articolo 4</description>
<author>Freephp.html.it</author>
</item>
</channel>
</rss>