Creare un feed RSS dinamico con PHP e MySQL

Giovanni Canella

16/08/2013

9002

Un feed RSS (Rich Site Summary) è un documento .xml, utilizzato per la distribuzione dei contenuti sul web.

E' il formato più diffuso grazie alla sua semplicità di utilizzo e versatilità, infatti aprendo un lettore di feed (o più comunemente chiamato feed reader), possiamo gestire le iscrizioni abbonandoci ai siti che ci interessano, e leggerene gli articoli senza aprire il browser.

Questo metodo ci permette di risparmiare un bel po' di tempo, dato che non dobbiamo ogni volta andare sul sito in questione e scrollare per vedere se ci sono novità. Se controlliamo anche più di un sito allora non possiamo non utilizzare i Feed!

Esempio feed Ginho con Lifrea

 

Obiettivo

Per generare un Feed RSS ci sono tool online che immettendo l'url del proprio sito fanno una "scansione" (a volte anche abbastanza approsimativa) e restituiscono un file .xml già compilato. (es. http://www.xml-sitemaps.com).

Xml sitemap generator

Unico svantaggio è che oltre al motivo espresso precedentemente, non possiamo affidarci a un sito che potrebbe andare offline da un momento all'altro e rimanere "a piedi" senza alcuna sitemap, per questi motivi, in questo articolo vedremo come crearla noi con un po' di XML e PHP!

 

Procedimento

In questo articolo utilizzeremo il paradigma orientato agli oggetti (OOP), per i motivi spiegati in un precedente articolo,  ma a nessuno vieta di rielaborare il codice per renderlo procedurale. Il procedimento è molto semplice, dato che non dobbiamo scrivere in nessun file, ma semplicemente stampare a video le informazioni principali dell'articolo, in appositi tag.

Ecco la struttura base:

/**
 * Classe per generare dinamicamente un feed RSS
 * 
 * @author Giovanni "Ginho" Canella
 * @param file string
 * @link http://ginho.it/articoli/61/creare-un-fed-rs-con-php
 * @return null
 */
class Feed {
	public function __construct($file, $configurazione) {

	}

	private function crea($file, $configurazione) {
	
	}

	private function connettiDatabase() {

	}
	
	private function mostraArticoli($limite) {
		
	}
}

Vediamo i tag per l'elemento <channel>:

Tag Descrizione Obbligatorio
<channel> Racchiude tutte le informazioni del feed. Ce ne può essere solo uno.

Si

<title> Indica il titolo del feed che verrà visualizzato durante la sottoscrizione.

Si

<link> L'url che punta al feed.

Si

<description> Mostra una descrizione generale del sito.

Si

<pubDate> Data di pubblicazione dell'elemento, conforme con lo standard RFC 822 (es. Aug, 10 2013 10:00:00 EST)

No

<lastBuildDate> Ultima modifica dell'elemento. (stesso discorso per il tag precedente)

No

<language>

Indica la lingua con cui è scritto il feed. (es. it-it,

No

<copyright> Informazioni generali sul copyright per i contenuti

No

<webmaster> Email di contatto dell'amministratore del sito

No

<category> Sezione in cui è stato scritto l'articolo

No

<generator> Indica con che metodo è stato generato il feed. (es. Ginho Feed Generator)

No

<ttl> (Time tLive), indica quanto tempo il feed deve rimanere nella cache prima che venga aggiornato. (indicato in minuti)

No

E quelli per <item>:

Tag Descrizione Obbligatorio
<item> Specifica un elemento.

Si

<title> Indica il titolo dell'articolo

Si

<link> Indica il link dell'articolo

Si

<description> Mostra una descrizione generale dell'articolo

Si

<pubDate> Quando è stato pubbicato l'articolo

No

<author> Indirizzo email dell'autore

No

<category> Sezione in cui è stato inserito l'articolo

No

<comments> Url in cui sono mostrati i commenti

No

<guid> (globally IniquIdentifier) Identifica univocamente l'articolo, usato per determinare se c'è un nuovo elemento.

No

Come possiamo vedere dall'ultima colonna, di entrambe le tabelle la maggior parte sono facoltativi, ma non per questo non bisogna metterli, anzi: grazie a quest'ultimi è possibile rendere ancora più ricco di informazioni il nostro feed, e renderlo più gradevole nell'utilizzo di un lettore.

Ora vediamo il codice:

 

connettiDatabase()

Semplice funzione per la connessione al database tramite PDO.

private function connettiDatabase() {
    try {
        $this->connessione = new PDO("mysql:host=localhost;dbname=nome_database", "username", "password");
    } catch(PDOException $e) {
        echo "Errore nella connessione al Database! <br>" . "<strong>" . $e->getMessage() . "</strong>";
    }
}

mostraArticoli($limite)

 

Ottiene gli articoli dal database, con un limite definito nella variabile $limite, passato come parametro come parametro e applicato grazie al comando LIMIT

$sql = $this->connessione->query("SELECT id, nome, data, introduzione FROM Articoli ORDER BY id DESC LIMIT " . $limite);

In questo caso non c'è bisogno di effettuare un prepared statement, dato che saremo noi a immettare il limite di articoli, e il dato non proviene da un form, ma basta query(). Successivamente iteriamo ogni articoli con il ciclo while, e stampiamo i valori appena estratti negli appositi tag, precedentemente illustrati:

while($row = $sql->fetch()) {
	$row["data"] = date("r", $row["data"]);
				 
    	echo "
		<item>
			<title>" . $row["nome"] . "</title>
			<link>http://" . $_SERVER["SERVER_NAME"] . "articoli.php?id_articolo=" . $row["id"] . "</link>
			<guid>http://" . $_SERVER["SERVER_NAME"] . "articoli.php?id_articolo=" . $row["id"] . "</guid>
			<pubDate>" . $row["data"] . "</pubDate>
			<description>
				<![CDATA[ 
					" . $row["introduzione"] . "
				]]>
			</description>
		</item>
   	 ";
}

Unica nota è utilizzo del parametro "r", nella funzione date, che formatta la data secondo le speciche RFC 2822, e il tag speciale CDATA,

<"[CDATA[   
	Dentro il tag CDATA posso inserire anche codice HTML!
]]>

obbligatorio perchè indica una porzione di testo che contiene dei caratteri che non fanno parte della struttura del documento. Questo perchè ogni elemento viene analizzato dal parser, fatta eccezione per quelli dentro quel tag.

 

crea($file)

Metodo principale che mostra l'instestazione del feed (ottenendo le impostazioni dall'array $configurazione, gli articoli, e i tag di chiusura

Come prima cosa si invia l'instestazione al browser dicendo di mostrare il contenuto come documento .xml. (text/xml), e poi si mostrano le informazioni principali.

header("Content-type: text/xml");

echo "<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>
		<channel>
			<title>" . $configurazione["nome"] . "</title>
			<link>http://" . $_SERVER["SERVER_NAME"] . "</link>
			<description><![CDATA[" . $configurazione["descrizione"] . "]]></description>
			<copyright>Copyright " . date("Y") . " " . $configurazione["amministratore"] . "</copyright>
			<managingEditor>" . $configurazione["email"] . " " . $configurazione["nome"] . "</managingEditor>
			<webMaster>" . $configurazione["email"] . " " . $configurazione["nome"] . "</webMaster>
			<language>it-it</language>
";
	
$this->mostraArticoli($configurazione["limite"]);

echo "</channel>
	</rss>
";

Ecco il codice finale:

/**
 * Classe per generare dinamicamente un feed RSS
 * 
 * @author Giovanni "Ginho" Canella
 * @param file string
 * @link http://ginho.it/articoli/61/creare-un-fed-rs-con-php
 * @return null
 */
class Feed {
	public function __construct($configurazione) {
		// Mi connetto al database
		$this->connettiDatabase();
		
		$this->crea($configurazione);
	}
	
	private function crea($configurazione) {
		header("Content-type: text/xml");

		echo "<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>
				<channel>
					<title>" . $configurazione["nome"] . "</title>
					<link>http://" . $_SERVER["SERVER_NAME"] . "</link>
					<description><![CDATA[" . $configurazione["descrizione"] . "]]></description>
					<copyright>Copyright " . date("Y") . " " . $configurazione["amministratore"] . "</copyright>
					<managingEditor>" . $configurazione["email"] . " " . $configurazione["nome"] . "</managingEditor>
					<webMaster>" . $configurazione["email"] . " " . $configurazione["nome"] . "</webMaster>
					<language>IT-it</language>
		";
		
		$this->mostraArticoli($configurazione["limite"]);
		
		echo "</channel>
			</rss>
		";
	}
	
	private function mostraArticoli($limite) {
		$sql = $this->connessione->query("SELECT id, nome, introduzione FROM articoli ORDER BY id DESC LIMIT " . $limite);

		while($row = $sql->fetch()) {
			$row["data"] = date("r", $row["data"]);
			 
			echo "
				<item>
					<title>" . $row["nome"] . "</title>
					<link>http://" . $_SERVER["SERVER_NAME"] . "/articoli.php?id_articolo=" . $row["id"] . "</link>
					<guid>http://" . $_SERVER["SERVER_NAME"] . "/articoli.php?id_articolo=" . $row["id"] . "</guid>
	   				<pubDate>" . $row["data"] . "</pubDate>
	   				<description>
	   					<![CDATA[ 
	   						" . $row["introduzione"] . "
	   					]]>
	   				</description>
				</item>
			";
		}
	}
	
	private function connettiDatabase() {
		try {
			$this->connessione = new PDO("mysql:host=localhost;dbname=nome_database", "username", "password");
		} catch(PDOException $e) {
			echo "Errore nella connessione al Database! <br>" . "<strong>" . $e->getMessage() . "</strong>";
		}
	}
}

Per mostrare il feed, dobbiamo creare un file che utilizzi la classe appena creata, es. crea_feed.php, e inseriamo:

$configurazione = array(
	"nome" => "Ginho",
	"descrizione" => "Il sito che parla di tutto ciò che ruota attorno all'informatica!",
	"amministratore" => "Giovanni Canella",
	"email" => "nostra.mail@provider.co.nz.it.com",
	"limite" => 10
);

new Feed($configurazione);

Ecco come sarà il risultato (lo si può vedere anche nel feed di Ginho!)

Risultato finale Feed RSS

I più letti

Ti potrebbero interessare