Générer du XML avec PHP
Bien souvent lorsque nous devons utiliser XML dans nos applications, qu’il s’agisse d’un fichier de configuration ou d’échanges de données, nous commençons dans un premier temps, par utiliser un fichier XML fait main et écrit directement depuis un éditeur de code.
Cette solution intermédiaire nous permet de brosser rapidement le tableau et mettre en place les premières briques de l’application.
Par contre, une fois l’application prototypée nous allons devoir utiliser un middleware pour prendre en charge la génération automatique de ce fichier.
En fonction du système d’information utilisé et de l’environnement de travail dans lequel nous opérons, nous allons avoir recours à diverses technologies. Au cours de cette étape, nous utiliserons le binôme PHP / MySQL afin de générer notre arborescence XML.
Deux approches, DOMXML (ou DOM) ou directement écrire dans le texte
Si vous utilisez PHP 4, il est possible d’avoir recours aux fonctions DOMXML et si vous utilisez PHP 5 vous vous orienterez plutôt du coté de DOM. Ces outils permettent de travailler et de directement manipuler la structure de fichiers XML.
Si cette approche à le mérite d’être très souple, adaptée et élégante, il reste cependant toujours possible de générer du contenu XML à la mode texte… donc en écrivant directement du XML sous sa forme littérale. Quelle que soit la méthode utilisée et en fonction des contextes, toutes conviennent, par contre, pour la suite de cet article, nous travaillons en mode littéral et donnerons la correspondance en PHP5.
De manière courte, générer un arbre XML reste une opération on ne peut plus simple. Il suffit, soit d’instancier un objet donnant accès au DOM (PHP 4 et PHP 5), soit de déclarer le prologue XML (mode littéral).
Puis, soit en ajoutant des nœuds par les fonctions adaptées (PHP 4 et PHP 5), soit en concaténant des bouts de chaines de caractères (mode littéral), de construire une à une l’intégralité des branches.
Dans les exemples ci-dessous, nous pouvons voir comment le fragment de code suivant est mis en place en fonction des trois solutions retenues, à savoir PHP 4, PHP 5 et Mode texte :
Code XML souhaité
<?xml version="1.0" encoding="utf-8"?> <items>contenu de la balise</items>
Génération en PHP4
<?php $xml = new domxml_new_doc('1.0'); $tag = $xml->create_element('items'); $text = $xml->create_text_node('contenu de la balise'); $tag->append_child($text); $xml->append_child($tag); echo $xml->dump_mem( true, 'UTF-8' ); ?>
Génération en PHP 5
<?php $xml = new DOMDocument('1.0', 'utf-8'); $tag = $xml->createElement('items','contenu de la balise'); $xml->appendChild($tag); echo $xml->saveXML(); ?>
Génération en mode littéral
<?php $xml = '<?xml version="1.0" encoding="UTF-8"?>'; $xml .= '<items>'; $xml .= 'contenu de la balise'; $xml .= '</items>'; echo $xml; ?>
Certes, le code est généré et correspond à notre attente, mais n’oublions pas que ce code intervient sur une réponse client serveur et va donc être renvoyé au demandeur. Il faut donc s’assurer que celui-ci soit donc livré dans un format adéquat et interprétable en tant que tel par le receveur.
Dans ce but nous allons regarder du coté du type MIME.
Type MIME du fichier
Le type mime permettant de renseigner sur la nature d’un document, nous devons nous assurer que le fichier XML renvoyé par le fichier PHP possède bien un type mime adéquat pour un arbre XML. L’un, php,étant de type application/x-httpd-php et l’autre, xml, de type application/xml ou text/xml.Nous devons donc ajouter l’une ou l’autre des instructions PHP suivantes pour modifier l’entête du fichier et s’assurer de bien retourner une arborescence XML,
header('Content-Type: text/xml'); header('Content-Type: application/xml');
Pour en savoir plus sur les types mimes employés par les fichiers rapprochez vous de l’article relativement complet : les types MIME par SelfHTML.
Formatage et encodage du fichier
De même, il est important de s’assurer que les caractères particuliers, tels que les caractères accentués, glyffes, et autres caractères spéciaux soient bien interprétés. Ainsi, il est préférable d’utiliser un encodage de caractères qui soit suffisamment large comme l’UTF-8.
Il ne suffit pas d’encoder seulement le fichier PHP qui génère l’arbre XML, mais également de veiller à ce que l’ensemble de la chaine, c’est à dire l’ensemble des fichiers utilisés tels que le fichier HTML, le code Javascript qui traitera l’information, les fichiers de connexion à la base de données, la base de données elle même, l’interclassement MySQL…. bref, s’assurer que tous convergent vers ce standard.
Généralement les navigateurs interprètent les documents text/xml comme s’il s’agissait de documents application/xml, ce qui revient à rendre l’utilisation de l’un ou de l’autre fréquemment confondue.
Cependant, il faut prendre en considération que les documents text/xml ne prennent pas en compte le prologue <?xml version="1.0" encoding="UTF-8"?>
et traitent le contenu comme s’il était encodé en US-ASCII, excepté si un entête HTTP le définit explicitement :
header('Content-type: text/html; charset=utf-8');
Attention, l’UTF-8 utilise, ou pas, une signature BOM (Bytes Order Mark) qui renforce la définition du type d’encodage utilisé. Bien que cette signature se veuille invisible pour la plupart des utilisateurs, elle peut apparaître dans certains affichages sous forme de trois caractères insignifiants .
Ces caractères viennent rendre inutilisable l’arborescence XML en créant une erreur, il faut donc retirer la signature utilisée pour l’encodage UTF-8.
NotePad++ permet de changer cette information depuis le menu Encodage > Convertir en UTF-8 (sans BOM), Dreamweaver permet également de le faire depuis le menu Modifier > Propriétés de la page onglet Titre / Codage.
Enfin, du fait que le fichier de connexion à la base est souvent un fichier lié, il faut s’assurer que la connexion et l’échange des informations sera bien maintenu en UTF-8. Pour cela, il est possible d’ajouter l’instruction suivante qui devrait garantir la bonne utilisation de l’encodage tout au long de la requête :
mysql_query("SET NAMES 'utf8'");
Vous pouvez vous rapprocher de l’article UTF-8 PHP MySQL (histoire d’encodage) pour creuser plus en avant le sujet de l’encodage et de l’échange de données client serveur basé sur PHP et MySQL.
Compléments d’entête
Afin de garantir une génération systématique du fichier XML à chaque requête et de ne pas piocher dans le cache, il peut être judicieux de compléter l’entête du fichier par deux déclarations.
La première Cache-Control devrait s’assurer de cela, et la seconde Expires (utilisant une date plus ancienne) venant renforcer le fait que le navigateur régénère le fichier et ne le pioche pas dans la cache, du fait même que la date de validité sera forcément dépassée.
header("Cache-Control: no-cache, must-revalidate"); header("Expires: Mon, 10 Jul 1990 05:00:00 GMT");
Vous pouvez consulter d’autres entêtes du protocole HTTP si vous souhaitez affiner certains points de votre fichier.
Autres points à ne pas négliger
Il existe encore quelques points dont il faut s’assurer afin de ne pas engendrer d’erreur. Par exemple, si vous générez un fichier PHP depuis Dreamweaver, celui-ci fabrique à la base un document HTML, donc toutes les balises <html>, <head> et <body> sont présentes.
Il faut les retirer pour, d’une part, ne pas compromettre la bonne validité du document XML et d’autre part, ne pas charger l’arborescence de nœuds qui n’auraient rien à faire dans le fichier généré.
Sur ce même point, le document PHP doit non seulement commencer par une balise <?php et non uniquement <?, mais de plus, cette balise ne doit pas être précédée d’un quelconque espace, qu’il s’agisse de plusieurs retours chariot ou d’un simple espace.
Détails du code
Une fois l’ensemble de ces points vérifiés, il ne reste plus qu’à générer l’arborescence XML. Voici par exemple une approche qui peut être retenue d’une part, en mode littéral et d’autre part, en utilisant l’objet DOMDocument en PHP5.
Vous pouvez si vous le souhaitez , récupérer et installer les fichiers nécessaires. Il suffit alors de créer une base de données nommée php_xml et d’y injecter la requête SQL fournie.
Ensuite, en lançant le fichier php_xml_5.php, ou le fichier php_xml_literal.php, l’arbre XML sera obtenu en retour.
Le fichier de connexion
<?php $dbhost = 'localhost'; $dbname = 'php_xml'; $dbuser = 'root'; $dbpass = ''; $conn = mysql_pconnect($dbhost, $dbuser, $dbpass); ?>
Le fichier PHP qui génère l’arborescence XML en mode littéral
<?php include_once("connect.php"); header('Content-Type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); header("Expires: Mon, 10 Jul 1990 05:00:00 GMT"); mysql_select_db($dbname, $conn); mysql_query("SET NAMES 'utf8'"); $sql = "SELECT * FROM `departements`"; $items = mysql_query($sql);
$xml = ‘<?xml version= »1.0″ encoding= »UTF-8″?>’;
if (mysql_num_rows($items) != 0){
$xml .= ‘<items>’;
while ($item = mysql_fetch_assoc($items)){
$xml .= ‘<item>’;
foreach($item as $key => $value){
$xml .= ‘<‘. $key . ‘>’;
$xml .= $value ;
$xml .= ‘</’. $key . ‘>’;
}
$xml .= ‘</item>’;
}
$xml .= ‘</items>’;
}
echo $xml;
?>
Et pour information, voici la version PHP5
<?php include_once("connect.php"); mysql_select_db($dbname, $conn); $sql = "SELECT * FROM `departements`"; $db_items = mysql_query($sql);
$xml = new DOMDocument(‘1.0’, ‘utf-8’);
if (mysql_num_rows($db_items) != 0){
$items = $xml->createElement(« items »);
while ($db_item = mysql_fetch_assoc($db_items)){
$item = $xml->createElement(« item »);
foreach($db_item as $key => $value){
$node = $xml->createElement($key,$value);
$item->appendChild($node);
}
$items->appendChild($item);
}
$xml->appendChild($items);
}
echo $xml->saveXML();
?>
Aller plus loin
XML
Natanya Pitts
Un livre indispensable qui vous fera découvrir pas à pas tous les avantages de Xml dans la publication Web. Vous apprendrez toutes les techniques qui vous permettront d'implémenter la technologie Xml dans vos développements Web, des concepts de base jusqu'au développement de vos propres Dtd en passant par la publication finale de vos documents....
Construire une application XML
Jean christophe Bernada et François Knab
Tous les grands acteurs (IBM, Microsoft, Oracle, Sun Microsystems, SAP, etc.) ont désormais placé XML au coeur de leurs produits et de leur stratégie technologique. En facilitant l'interface entre les applications Web et les bases de données, XML devient un élément pivot des architectures Internet/intranet et Web client-serveur. Point fort de ce livre, deux études de cas tirées d'applications aujourd'hui en production chez des clients de CosmosBay : l'une est bâtie sur les technologies ...
Initiation à XML
David Hunter
Ce livre a pour objectif de répondre à ces interrogations et de conduire le lecteur pas à pas jusqu'aux aspects les plus avancés de XML : feuilles de style CSS et transformations XSLT, écriture de DTD et de schémas XML, traitement de documents XML à l'aide des interfaces DOM et SAX, etc. L'ouvrage est illustré de trois études de cas detaillées, destinées à préparer le lecteur au developpement d'applications professionnelles....
Manuel de prise en main de XML
Kevin Howard Goldberg
Cet ouvrage est avant tout un didacticiel pour apprendre à utiliser XML. Sa présentation claire et efficace ainsi ses exemples de code pratiques et très visuels en font un outil de référence pour tous les débutants, étudiants ou professionnels, qui doivent savoir créer un document XML, le transformer dans un autre format (dont HTML) avec XSL, et définir sa structure avec les DTD et XML Schema. Il présente également certains langages en cours de développement, les nouvelles versions d...