Mis à jour le mercredi 30 octobre 2013
  • Facile
Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Introduction du cours

Bonjour, bonjour ! :)

Vous voulez créer votre propre flux RSS de news pour votre site ?
Vous voulez utiliser une librairie (lib) XML pour avoir un code plus joli, plus propre, mais vous ne trouvez aucun tutoriel à ce sujet sur Google ?

J'ai celui qu'il vous faut. ^^

Quelques notions utiles

Pour commencer, nous allons aborder les bases qui me semblent nécessaires pour comprendre la suite du tuto, et surtout examiner le fonctionnement de la lib XML.
Elle n'est vraiment pas difficile à comprendre (c'est bien pour cela que je l'utilise :-° ), mais sans quelques mots de vocabulaire, vous aurez du mal à voir de quoi je parle.

Prenons par exemple un fichier XML « au hasard » (bon, pas vraiment au hasard : il nous servira encore par la suite).

<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
        <channel>
                <description>Une description</description>
                <link>Un lien</link>
                <title>Oh, un titre ! :D</title>
        </channel>
</rss>

<channel> est ce que l'on appelle une balise. Comme vous le savez, les balises vont par « paires », c'est-à-dire qu'il y a une balise ouvrante et une balise fermante.
Dans cet exemple avec <channel>, la balise ouvrante est <channel> et la balise fermante </channel>.
Il y a aussi les balises autofermantes comme <img />, mais elles ne nous intéressent pas dans cet article.
Une balise peut en outre prendre un (ou plusieurs) arguments ; par exemple, version est un argument de la balise <rss> qui a pour valeur 2.0.

Si vous voulez en savoir plus au sujet du XML, voici un excellent article écrit par un Zéro.

Quelques mots concernant la lib que nous utiliserons pour parser le fichier XML afin de créer notre flux RSS : il s'agira de DomXML pour PHP4.
Pour la documentation officielle, c'est par ici. Avec cette documentation et un peu de logique, vous pouvez faire énormément de choses. ;)

À présent, parlons un peu vocabulaire : voici quelques informations qui vous aideront à comprendre le nom des fonctions de DomXML. ^^
Dans notre fichier XML, la balise <channel> est aussi appelée « node » (« nœud », en français). Elle fait partie d'un node root (nœud parent), ici <rss>. On dit aussi que <channel> est une balise fille ou un fils (child) de <rss>.
Si vous avez bien compris cela, vous avez sans doute déduit que les balises <description>, <link> et <title> sont des enfants de <channel>.

En résumé, on a :

  • <channel>, appelée « node » dans la lib XML. C'est le node root de <description> ;

  • <description>, appelée « child » dans la lib XML.

Structure du document XML

Après avoir vu un peu de vocabulaire utile à la compréhension du tutoriel, nous allons nous intéresser à la structure que devra respecter le fichier XML pour être lisible par un lecteur de flux RSS. Prenons pour exemple le Site du Zéro. :-°

Voici la structure du début du fichier.

<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
        <channel>
                <description>Description du site</description>
                <link>Lien vers le site</link>
                <title>Titre du site</title>
        </channel>
</rss>

C'est la base d'un fichier XML pouvant être lu par un lecteur de flux RSS. Bien sûr, vous pouvez ajouter des éléments.

À présent, étudions la structure d'un élément (dans notre cas, une news) qui est à mettre entre les balises <channel></channel> du fichier XML vu précédemment. ;)

<item>
        <title>Titre de la news</title>
        <link>Lien vers la news en entier</link>
        <description>Description de la news, le mieux étant de mettre le contenu de la news</description>
        <comments>Un lien vers des commentaires de news</comments>
        <author>Auteur de la news</author>
        <pubDate>Date de publication de la news</pubDate>
        <guid>Texte qui identifie de manière unique la news, le mieux étant de mettre le titre de la news</guid>
        <source>Source dont est tirée la news</source>
</item>

Quelques explications s’imposent. Le nœud item va correspondre à une news dans la liste des news du fichier XML, c'est-à-dire qu'une fois votre fichier XML construit, vous aurez sans doute quelque chose ressemblant à ceci :

<item>
<!-- Titre, lien, etc. de la première news -->
</item>
<item>
<!-- Titre, lien, etc. de la deuxième news -->
</item>
<item>
<!-- etc. -->
</item>

Voilà, cette structure vous permettra d'obtenir un flux RSS assez complet ; bien sûr, vous pouvez ajouter encore plus de choses. ;)

Récupérer les news

Une fois que l'on connaît la manière dont doit être construit le document XML, il est temps de savoir comment récupérer le contenu qu'il faut y insérer. :D

Tout d'abord, jetons un œil à la structure de la table news servant de modèle pour ce tuto.

CREATE TABLE `news` (
  `nws_id` smallint(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `nws_pseudo` varchar(255) NOT NULL DEFAULT '0',
  `nws_titre` varchar(255) NOT NULL DEFAULT '',
  `nws_contenu` text NOT NULL,
  `nws_date` int(10) NOT NULL DEFAULT '0',
  PRIMARY KEY `id` (`nws_id`),
) TYPE=InnoDB COMMENT='Contient les news' AUTO_INCREMENT=59 ;

Cette table n'a rien d'exceptionnel ; si vous ne la comprenez pas, c’est que vous n'avez pas suivi les cours de M@teo correctement. :-°

Intéressons-nous à la requête destinée à sélectionner les différents éléments.

SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news ORDER BY nws_date DESC LIMIT 10 OFFSET 0

Maintenant, il ne nous reste plus qu'à envoyer la requête au serveur MySQL.

<?php
mysql_connect("localhost", "root", "mdp");
mysql_select_db("nom_bdd");
 
$nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
?>

Ici, on sélectionne les dix dernières news. Libre à vous de modifier cette valeur.
Et voilà. Ces quelques lignes de code ne devraient pas vous surprendre si vous avez lu le tuto depuis le début. :)

Il ne vous reste plus qu'à vous souvenir que $nws contient la liste des news que vous voulez mettre dans votre flux RSS.

Créer le fichier XML

Nous sommes presque arrivés au bout de nos peines. Plus que quelques minutes d'attention et vous aurez enfin votre flux RSS. ^^

Voici la ligne de code permettant d'initialiser le fichier XML :

<?php
$xml_file = domxml_new_doc("1.0");
?>

Cette ligne crée simplement un fichier XML temporaire en mémoire dans lequel on indique la version XML utilisée (ici : version 1.0).

À présent, voyons comment créer le nœud maître rss puis un nœud fils channel.

<?php
function &init_news_rss(&$xml_file)
{
        $root = $xml_file->create_element("rss"); // création de l'élément
        $root->set_attribute("version", "2.0"); // on lui ajoute un attribut
        $root = $xml_file->append_child($root); // on l'insère dans le nœud parent (ici root, qui est "rss")
        
        $channel = $xml_file->create_element("channel");
        $channel = $root->append_child($channel);
                
        $desc = $xml_file->create_element("description");
        $desc = $channel->append_child($desc);
        $text_desc = $xml_file->create_text_node("Partage de connaissances en tous genres"); // on insère du texte entre les balises <description></description>
        $text_desc = $desc->append_child($text_desc);
        
        $link = $xml_file->create_element("link");
        $link = $channel->append_child($link);
        $text_link = $xml_file->create_text_node("http://www.bougiemind.info");
        $text_link = $link->append_child($text_link);
        
        $title = $xml_file->create_element("title");
        $title = $channel->append_child($title);
        $text_title = $xml_file->create_text_node("Bougie'S mind");
        $text_title = $title->append_child($text_title);
        
        return $channel;
}
?>

Cette fonction retourne une référence : ainsi n'obtient-on pas une simple copie de l'élément, mais bien l'élément lui-même. ;)

À présent, vous avez un fichier XML (toujours en mémoire) qui devrait ressembler à ceci :

<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
        <channel>
                <description>Partage de connaissances en tous genres</description>
                <link>http://www.bougiemind.info</link>
                <title>Bougie'S mind</title>
        </channel>
</rss>

Maintenant, nous allons passer à la partie la plus difficile à comprendre (je vous rassure, elle est quand même tout à fait abordable) : la création des items (chaque item correspond à une news différente).
La fonction prend comme arguments :

  • $parent, contient le fichier XML temporaire ;

  • $root, nœud parent, ici channel ;

  • $id, ID de la news ;

  • $pseudo, auteur de la news ;

  • $titre, titre de la news ;

  • $contenu, contenu de la news ;

  • $date, date de création de la news.

<?php
function add_news_node(&$parent, $root, $id, $pseudo, $titre, $contenu, $date)
{
        $item = $parent->create_element("item");
        $item = $root->append_child($item);
        
        $title = $parent->create_element("title");
        $title = $item->append_child($title);
        $text_title = $parent->create_text_node($titre);
        $text_title = $title->append_child($text_title);
        
        $link = $parent->create_element("link");
        $link = $item->append_child($link);
        $text_link = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
        $text_link = $link->append_child($text_link);
        
        $desc = $parent->create_element("description");
        $desc = $item->append_child($desc);
        $text_desc = $parent->create_text_node($contenu);
        $text_desc = $desc->append_child($text_desc);
        
        $com = $parent->create_element("comments");
        $com = $item->append_child($com);
        $text_com = $parent->create_text_node("http://www.bougiemind.info/news-11-".$id.".html");
        $text_com = $com->append_child($text_com);
        
        $author = $parent->create_element("author");
        $author = $item->append_child($author);
        $text_author = $parent->create_text_node($pseudo);
        $text_author = $author->append_child($text_author);
        
        $pubdate = $parent->create_element("pubDate");
        $pubdate = $item->append_child($pubdate);
        $text_date = $parent->create_text_node($date);
        $text_date = $pubdate->append_child($text_date);
        
        $guid = $parent->create_element("guid");
        $guid = $item->append_child($guid);
        $text_guid = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
        $text_guid = $guid->append_child($text_guid);
        
        $src = $parent->create_element("source");
        $src = $item->append_child($src);
        $text_src = $parent->create_text_node("http://www.bougiemind.info");
        $text_src = $src->append_child($text_src);
}
?>

Normalement, aucune de ces fonctions ne vous est inconnue : elles ont été décrites plus haut. ;)

Voici à quoi ressemble le bout de fichier XML que vous venez de créer.

<item>
    <title>Flux RSS des news en place</title>
    <link>http://www.bougiemind.info/rss_news56.html</link>
    <description>Voilà, le flux RSS des news est en place !</description>
    <comments>http://www.bougiemind.info/news-11-56.html</comments>
    <author>Bougie</author>
    <pubDate>24/04/2006 12:42</pubDate>
    <guid>http://www.bougiemind.info/rss_news56.html</guid>
    <source>http://www.bougiemind.info</source>
</item>

Il ne nous reste plus qu'à élaborer une boucle sur la fonction add_news_node afin de créer un élément item à chaque fois qu'il y a une news. Je vous laisse réfléchir. ;)

Vous avez réfléchi ? Bon, je ne vous fais pas patienter plus longtemps. ^^

<?php
while($news = mysql_fetch_assoc($nws))
        {
                add_news_node($xml_file, $channel, $news["nws_id"], $news["nws_pseudo"], $news["nws_titre"], $news["nws_contenu"], date("d/m/Y H:i", $news["nws_date"]));
        }
?>

Le paramètre de la fonction add_news_node ($channel) est l'objet retourné par la fonction init_news_rss.

À présent, il ne reste plus qu'à enregistrer le fichier XML sur le disque dur. ^^

<?php
$xml_file->dump_file("news_FR_flux.xml");
?>

Vous devriez désormais avoir un flux RSS fonctionnel.

Faciliter l'utilisation

Maintenant que l'on a vu comment faire un flux RSS, on va essayer de mettre un peu d'ordre dans ce code qui, pour le moment, est assez brouillon : on va tout regrouper dans un fichier flux_rss.php.

Nous allons également créer une fonction qui s'occupera de mettre à jour le flux RSS :

<?php
function rebuild_rss()
{
        // on se connecte à la BDD
        mysql_connect("localhost", "root", "mdp");
        mysql_select_db("votre_table");
 
        // on récupère les news
        $nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
 
        // on crée le fichier XML
        $xml_file = domxml_new_doc("1.0");
 
        // on ajoute chaque news au fichier RSS
        while($news = mysql_fetch_assoc($nws))
        {
                add_news_node($xml_file, $channel, $news["nws_id"], $news["nws_pseudo"], $news["nws_titre"], $news["nws_contenu"], date("d/m/Y H:i", $news["nws_date"]));
        }
        
        // on écrit le fichier
        $xml_file->dump_file("news_FR_flux.xml");
}
?>

Vous avez maintenant une fonction qui reconstruira votre flux RSS à chaque fois que vous l'appellerez. ;)

Si on récapitule, vous devriez avoir un fichier flux_rss.php comme celui-ci :

<?php
function &init_news_rss(&$xml_file)
{
        $root = $xml_file->create_element("rss"); // création de l'élément
        $root->set_attribute("version", "2.0"); // on lui ajoute un attribut
        $root = $xml_file->append_child($root); // on l'insère dans le nœud parent (ici root qui est "rss")
       
        $channel = $xml_file->create_element("channel");
        $channel = $root->append_child($channel);
               
        $desc = $xml_file->create_element("description");
        $desc = $channel->append_child($desc);
        $text_desc = $xml_file->create_text_node("Partage de connaissances en tous genres"); // on insère du texte entre les balises <description></description>
        $text_desc = $desc->append_child($text_desc);
       
        $link = $xml_file->create_element("link");
        $link = $channel->append_child($link);
        $text_link = $xml_file->create_text_node("http://www.bougiemind.info");
        $text_link = $link->append_child($text_link);
       
        $title = $xml_file->create_element("title");
        $title = $channel->append_child($title);
        $text_title = $xml_file->create_text_node("Bougie'S mind");
        $text_title = $title->append_child($text_title);
       
        return $channel;
}
 
function add_news_node(&$parent, $root, $id, $pseudo, $titre, $contenu, $date)
{
        $item = $parent->create_element("item");
        $item = $root->append_child($item);
       
        $title = $parent->create_element("title");
        $title = $item->append_child($title);
        $text_title = $parent->create_text_node($titre);
        $text_title = $title->append_child($text_title);
       
        $link = $parent->create_element("link");
        $link = $item->append_child($link);
        $text_link = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
        $text_link = $link->append_child($text_link);
       
        $desc = $parent->create_element("description");
        $desc = $item->append_child($desc);
        $text_desc = $parent->create_text_node($contenu);
        $text_desc = $desc->append_child($text_desc);
       
        $com = $parent->create_element("comments");
        $com = $item->append_child($com);
        $text_com = $parent->create_text_node("http://www.bougiemind.info/news-11-".$id.".html");
        $text_com = $com->append_child($text_com);
       
        $author = $parent->create_element("author");
        $author = $item->append_child($author);
        $text_author = $parent->create_text_node($pseudo);
        $text_author = $author->append_child($text_author);
       
        $pubdate = $parent->create_element("pubDate");
        $pubdate = $item->append_child($pubdate);
        $text_date = $parent->create_text_node($date);
        $text_date = $pubdate->append_child($text_date);
       
        $guid = $parent->create_element("guid");
        $guid = $item->append_child($guid);
        $text_guid = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
        $text_guid = $guid->append_child($text_guid);
       
        $src = $parent->create_element("source");
        $src = $item->append_child($src);
        $text_src = $parent->create_text_node("http://www.bougiemind.info");
        $text_src = $src->append_child($text_src);
}
 
function rebuild_rss()
{
        // on se connecte à la BDD
        mysql_connect("localhost", "root", "mdp");
        mysql_select_db("votre_table");
 
        // on récupère les news
        $nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
 
        // on crée le fichier XML
        $xml_file = domxml_new_doc("1.0");
 
        // on initialise le fichier XML pour le flux RSS
        $channel = init_news_rss($xml_file);
 
        // on ajoute chaque news au fichier RSS
        while($news = mysql_fetch_assoc($nws))
        {
                add_news_node($xml_file, $channel, $news["nws_id"], $news["nws_pseudo"], $news["nws_titre"], $news["nws_contenu"], date("d/m/Y H:i", $news["nws_date"]));
        }
       
        // on écrit le fichier
        $xml_file->dump_file("news_FR_flux.xml");
}
?>

Et voilà le travail ! Il vous suffit à présent d'ajouter deux lignes de code pour que votre flux RSS soit reconstruit :

<?php
require('flux_rss.php');
rebuild_rss();
?>

Il ne vous reste plus qu'à indiquer au navigateur que votre site possède un flux RSS, et pour cela une simple ligne en XHTML suffit.

<link rel="alternate" type="application/rss+xml" title="{Titre du flux RSS}" href="{Lien vers le flux RSS}" />

{Titre du flux RSS} et {Lien vers le flux RSS} sont bien sûr à remplacer par ce que vous voulez. :)

Passage à PHP5

Pour ceux qui souhaitent utiliser mon code avec PHP5, il y a quelques trucs à changer (c'est principalement le nom des méthodes qui change).

Le nom de la lib XML n'est plus DOMXML mais simplement DOM.
Un lien vers la documentation.

Je ne vais pas recopier le code modifié car il est, à peu de choses près, identique (et puis c’est assez répétitif ;) ).

  • La fonction create_element est à remplacer par createElement.

  • La fonction set_attribute est à remplacer par setAttribute.

  • La fonction append_child est à remplacer par appendChild.

  • La fonction create_text_node est à remplacer par createTextNode.

Ce qui nous donnerait (par exemple) pour la fonction &init_news_rss(&$xml_file) :

<?php
function &init_news_rss(&$xml_file)
{
        $root = $xml_file->createElement("rss"); // création de l'élément
        $root->setAttribute("version", "2.0"); // on lui ajoute un attribut
        $root = $xml_file->appendChild($root); // on l'insère dans le nœud parent (ici root qui est "rss")
       
        $channel = $xml_file->createElement("channel");
        $channel = $root->appendChild($channel);
               
        $desc = $xml_file->createElement("description");
        $desc = $channel->appendChild($desc);
        $text_desc = $xml_file->createTextNode("Partage de connaissances en tous genres"); // on insère du texte entre les balises <description></description>
        $text_desc = $desc->appendChild($text_desc);
       
        $link = $xml_file->createElement("link");
        $link = $channel->appendChild($link);
        $text_link = $xml_file->createTextNode("http://www.bougiemind.info");
        $text_link = $link->appendChild($text_link);
       
        $title = $xml_file->createElement("title");
        $title = $channel->appendChild($title);
        $text_title = $xml_file->createTextNode("Bougie'S mind");
        $text_title = $title->appendChild($text_title);
       
        return $channel;
}
?>

À vous ensuite de modifier les autres fonctions ! Je vous fais confiance. ;)

Les dernières modifications doivent se faire au niveau de la création du fichier XML et de sa sauvegarde.

Dans notre code PHP4, on avait :

<?php
$xml_file = domxml_new_doc("1.0");
?>

En PHP5, il faut faire comme cela :

<?php
$xml_file = new DOMDocument("1.0");
?>

Et pour sauvegarder le fichier XML…
En PHP4 :

<?php
$xml_file->dump_file("news_FR_flux.xml");
?>

En PHP5 :

<?php
$xml_file->save("news_FR_flux.xml");
?>

Vous avez désormais un code qui fonctionnera sur un serveur avec PHP5 !
Et n'oubliez pas : tout ce que je vous ai dit ici, je l'ai trouvé dans la documentation. ;)

Vous devriez maintenant être capables de coder votre propre flux RSS des news de votre site en vous servant d'une lib XML.
Merci de m'avoir lu, et à bientôt pour de nouvelles aventures. :-°

P.-S. — À ceux qui souhaitent finaliser le tuto en ajoutant ce qui a été dit dans les commentaires, envoyez-moi un MP. ;)

Exemple de certificat de réussite
Exemple de certificat de réussite