Programmation PHP/DOMDocument
Introduction.
Une des recherches majeures du développeur a toujours été de chercher à séparer les langages de programmation, clarifiant ainsi ses scripts et simplifiant sa tâche. Ainsi, il est possible d'enregistrer son CSS dans des fichiers externes comportant l'extension .css, de séparer le javascript du HTML en l'enregistrant dans des fichiers .js.
Il reste cependant le problème de la séparation du PHP et du XHTML. La librairie va repousser ces limites.
Qu'est-ce que DOMDocument ?
DOMDocument est une librairie de fonctions apparue avec PHP5 et activée par défaut. Elle permet de concevoir des pages HTML sous forme d'objets. 
Les avantages et les inconvénients.
mais...
Principe du DOM.
Cette librairie présente de nombreuses similitudes avec le javascript aussi bien dans le fonctionnement que dans le nom de ses fonctions.
Le DOM (Document Object Model) est basée sur un système de nodes.
Un node est un élément qui est
- soit une balise (nodes Tag)
- soit du texte
- soit un attribut de balise
Les nodes sont liés par un système hiérarchique :
<p>Ce texte est <strong>important</strong></p>
On dit alors que le node Tag <strong> est fils du node <p>
Le node texte "Ce texte est" est également fils de <p> qui est parent du node texte.
Il existe un certain nombre de classes prédéfinies : DOMDocument, DOMNode, DOMElement, DOMText, DOMAttr, DOMList... Certaines sont très simples, d'autres possèdent des fonctionnalités très avancées.
Importer une page préexistante.
Il est possible d'importer une page HTML. Cela simplifiera considérablement la tâche du programmeur qui n'aura qu'à apporter les modifications nécessaires avant de l'afficher ou de réenregistrer la page.
Voici le code important la page.
<?php
$doc = DOMDocument::loadHTMLFile("fichier.html");
La variable $doc contient donc un objet DOMDocument avec toutes les balises sous formes de nodes. Il est maintenant possible d'accéder aux nodes par le biais de fonctions préexistantes.
NB : il est également possible d'avoir recours au code suivant.
<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("fichier.html");
Il est également possible d'importer le code à partir d'une chaîne de caractères :
<?php
$code = "<html><head></head><body></body></html>";
$doc = new DOMDocument();
$doc->loadHTML( $code );
Enregistrer une page.
Un des grands avantages de cette librairie est la capacité à enregistrer la page générée dans un fichier pour un affichage ultérieur. Il suffit d'avoir recours au code suivant :
$doc->saveHTMLFile("fichier.html");
Si vous voulez l'afficher, il vous suffit d'exécuter la fonction suivante :
<?php
echo $doc->saveHTML();
La méthode retourne une chaîne de caractères que la fonction codice_1 affiche.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr-FR">
 <head>
 <meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
 </head>
 <body>
<?php
$code = 'Les àâçéèêëîïôöüù';
echo $code; // affichage normal
$page = new DOMDocument();
$page->loadHTML($code);
echo $page->saveHTML(); // Les Ã Ã¢Ã§Ã©Ã¨ÃªÃ«Ã®Ã¯Ã´Ã¶Ã¼Ã¹
// Solution
$page2 = new DOMDocument();
$page2->loadHTML(utf8_decode($code));
echo $page2->saveHTML(); // Les àâçéèêëîïôöüù
 </body>
</html>
La classe DOMNode.
Les classes DOMElement, DOMText et DOMAttribute sont dérivées de cette classe. Ainsi, les méthodes et propriétés présentées ici seront disponibles pour leurs classes filles.
Attention : un node une fois créé ne se trouve pas dans le document. Ajouter un node va se dérouler en deux étapes :
- on crée le node
- on l'insère dans le node parent ou à la racine du document.
Voici les propriétés accessibles à tous les nodes :
$node->nodeType // Type de node. Vaut 1 pour un élément XML, 3 pour un texte
$node->childNodes //Retourne un objet NodeList qui contient tout les éléments enfants de ce node
$node->firstChild //Retourne le premier node enfant
$node->lastChild // Retourne le dernier node enfant
$node->previousSibling // Retourne le node juste avant celui-ci
$node->nextSibling // Retourne le node juste après celui-ci
Les méthodes sont les suivantes
Le node $enfant devient enfant de $node
$node->appendChild( $enfant );
Supprime le node $enfant du node $node
$node->removeChild( $enfant );
La classe DOMElement.
$node->tagName // par exemple "p" pour un paragraphe. Sa valeur ne peut être modifiée
Attention : seules les principales propriétés sont présentées. Si vous voulez en avoir la liste complète, vous pouvez consulter la documentation de référence sur http://php.net/manual/fr/class.domnode.php.
- Méthodes d'attributs
$node->hasAttribute(); //Renvoie true si il possède des attributs
$node->getAttribute("name"); //Retourne la valeur de l'attribut
$node->removeAttribute("name"); //Supprime l'attribut "name"
$node->setAttribute("name","value"); //Modifie un attribut
$node->getAttributeNode ("name" ); //Retourne un objet DOMAttr
- Autres méthodes
$newNode = $node->cloneNode(); //duplique un élément
$nodeList = $node->getElementsByTagName("strong");
Cette fonction retourne un objet "nodeList" qui contient une liste des balises <strong> enfants du node. Pour récupérer le n+1ème node de la liste, il suffit d'avoir recours à la méthode de l'objet "nodeList" suivante :
$strong5 = $nodeList->item(4); //Sélectionne la 5e balise <strong>
L'attribut "length" donne le nombre d'éléments de la liste. Exemple :
for ($i=0; $i<$nodeList->length; $i++)
 echo $nodeList->item( $i )->tagName;
Comme vous le savez, "tagName" retourne le nom de la balise. Ici, le code retournera "strongstrongstrong…". En effet, seuls les nodes "strong" ont "été sélectionné.
Comme vous avez pu le remarquer, il est possible d'exécuter plusieurs méthodes et propriétés en même temps. Voici l'ordre d'exécution :
- La méthode item($i) est exécutée et retourne un "nodeTag".
- La propriété "tagName" du node est appelée. Attention : c'est celle de l'objet retourné.
- La fonction "echo" affiche le nom de la balise retournée par la propriété "tagName".
La classe DOMText.
La classe DOMText contient l'unique propriété suivante :
$node->wholeText
Elle n'est accessible qu'en lecture seule.
La classe "DOMText" admet deux méthodes :
/* Retourne true si la chaîne de caractère contient des espaces */
$node->isWhitespaceInElementContent();
/* Retourne dans $end un objet Text qui contient la fin du texte de $node.
$node ne contiendra plus que les 5 premiers caractères de sa chaîne */
$end = $node->splitText(5)
Exemple :
<?php
$doc = new DOMDocument();
$text = $doc->createTextNode("Je suis celui qui est");
$text2 = $text->splitText(7);
echo $text->wholeText."<br />";
echo $text2->wholeText
Ce code retournera "je suis<br /> celui qui est"
La classe DOMAttr.
La classe DOMAttr est comme son nom l'indique un attribut, qui est donc dépendant de la balise.
Elle contient les propriétés suivantes :
$node->name // Nom de l'attribut
$node->value // Valeur de l'attribut
/* Nom de la balise qui contient l'attribut. La valeur retournée est un objet DOMElement */
$node->ownerElement 
Seule la propriété value n'est pas en lecture seule, c'est à dire qu'il est possible d'avoir recours au code suivant :
$node->value = "maValeur";
Accéder à un node.
Il existe plusieurs modes de recherche du node. Il est par exemple possible de le sélectionner par son id :
$node = $doc->getElementById("sonId"); //Retourne un objet node
Sachant qu'il ne peut y avoir qu'un node possédant l'id recherché, la méthode retournera un objet node au lieu d'un objet nodeList.
Il est cependant possible de récupérer une liste de nodes en les sélectionnant par leur nom de balise. Évidemment, seuls les nodes Tag peuvent être sélectionnés.
$nodeList = $doc->getElementsByTagName("acronym"); //Sélectionne toutes les balises <acronym>
Comme nous l'avons déjà dit, il faut, pour récupérer un node particulier de la liste, utiliser la méthode suivante :
$acronym5 = $nodeList->item(4); //Sélectionne le 5e node de la liste;
XML.
// Création
$xml = new DOMDocument("1.0", "ISO-8859-15");
$xml_node1 = $xml->createElement("Node_1");
$xml_node2 = $xml->createElement("Node_2", "Feuille");
$xml_node2->setAttribute("Attribut_1", "Valeur_1");
$xml_node1->appendChild($xml_node2);
$xml->appendChild($xml_node1);
$xml->save('Fichier_1.xml');
// Lecture
$xml = new DomDocument;
$xml->load('Fichier_1.xml');
$nodes = $xml->getElementsByTagName("Node_2");
var_dump($nodes);