W3docs

Guide de référence de la bibliothèque PHP libxml

Guide sur l'extension PHP libxml : capturer les erreurs d'analyse, valider du XML avec SimpleXML ou DOM, et éviter les attaques XXE.

Ce guide couvre l'extension PHP libxml : ce qu'elle est, comment les parseurs XML de PHP signalent les erreurs à travers elle, et comment analyser, valider et manipuler du XML en toute sécurité. L'idée clé à retenir est que libxml est la couche partagée de signalement d'erreurs et de configuration sous-jacente à SimpleXML, DOM et XMLReader — une fois que vous la comprenez, chaque extension XML de PHP devient plus facile à déboguer.

Qu'est-ce que PHP libxml ?

libxml est la bibliothèque C que PHP utilise pour presque tout son traitement XML. L'extension PHP libxml expose la gestion des erreurs et les options du parseur de cette bibliothèque à votre code. Vous l'appelez rarement directement — vous utilisez plutôt une extension de plus haut niveau construite par-dessus :

  • SimpleXML — la façon rapide et proche des tableaux pour lire du XML.
  • DOM (DOMDocument) — accès complet en lecture/écriture à l'arbre du document.
  • XMLReader / XMLWriter — analyse en flux, efficace en mémoire, pour les grands fichiers.

Quand l'un de ces parseurs rencontre du XML mal formé, il signale le problème via libxml. Les fonctions libxml_* vous permettent de capturer, d'inspecter et de vider ces erreurs.

Installer PHP libxml

L'extension libxml est incluse et activée par défaut — il n'y a rien à installer. Vous pouvez confirmer qu'elle est active à l'exécution :

<?php
var_dump(extension_loaded('libxml')); // bool(true)
echo LIBXML_DOTTED_VERSION;            // e.g. "2.9.14" — the linked libxml2 version
?>

Si une compilation personnalisée retourne false, recompilez PHP avec --with-libxml (les anciennes versions utilisaient --enable-libxml).

Gérer les erreurs libxml

C'est la partie la plus importante de l'extension. Par défaut, un document mal formé émet des avertissements PHP, ce qui est difficile à gérer en production. Utilisez plutôt le mode d'erreur interne : libxml collecte alors les erreurs dans un tampon que vous lisez vous-même.

<?php
// Stop warnings; buffer errors instead.
libxml_use_internal_errors(true);

$broken = '<root><item>unclosed</root>';
$xml = simplexml_load_string($broken);

if ($xml === false) {
  foreach (libxml_get_errors() as $error) {
    // Each $error is a LibXMLError object.
    printf(
      "[%s] line %d: %s",
      $error->level === LIBXML_ERR_FATAL ? 'fatal' : 'warning',
      $error->line,
      trim($error->message)
    );
    echo PHP_EOL;
  }
  libxml_clear_errors(); // Empty the buffer so it doesn't leak into later parses.
}
?>

Un objet LibXMLError expose level (LIBXML_ERR_WARNING, LIBXML_ERR_ERROR, LIBXML_ERR_FATAL), code, message, line, column et file. Fonctions associées :

Analyser des documents XML

L'utilisation la plus courante du XML en PHP est la lecture d'un document. simplexml_load_string() (et son équivalent fichier simplexml_load_file()) retournent false en cas d'échec, donc associez-les toujours au mode d'erreur interne :

<?php
libxml_use_internal_errors(true);

$source = '<catalog><book id="1">PHP Basics</book></catalog>';
$xml = simplexml_load_string($source);

if ($xml === false) {
  echo "Failed to parse XML." . PHP_EOL;
  foreach (libxml_get_errors() as $error) {
    echo trim($error->message) . PHP_EOL;
  }
  libxml_clear_errors();
} else {
  echo "Loaded: " . $xml->book . PHP_EOL;      // Loaded: PHP Basics
  echo "id = " . $xml->book['id'] . PHP_EOL;    // id = 1
}
?>

Options du parseur (constantes libxml)

La plupart des fonctions XML acceptent un masque de bits $options composé de constantes LIBXML_*. Combinez-les avec l'opérateur OU bit à bit (|) :

<?php
$xml = simplexml_load_string(
  '<a>  <b>text</b>  </a>',
  'SimpleXMLElement',
  LIBXML_NOCDATA | LIBXML_NOBLANKS // drop CDATA wrappers + ignore whitespace-only nodes
);
echo $xml->b; // text
?>

Options fréquemment utilisées :

ConstanteEffet
LIBXML_NOBLANKSSupprimer les nœuds vides (espaces blancs uniquement).
LIBXML_NOCDATAFusionner les sections CDATA en texte brut.
LIBXML_NOERROR / LIBXML_NOWARNINGSupprimer les erreurs / avertissements.
LIBXML_COMPACTOptimisation pour les petits nœuds dans les grands documents.
LIBXML_NOENTSubstituer les entités — dangereux avec des entrées non fiables (voir ci-dessous).

Sécurité : XML non fiable et XXE

Les attaques XML eXternal Entity (XXE) permettent à un document malveillant de lire des fichiers locaux ou de déclencher des requêtes réseau. Ne jamais activer le chargement des entités sur des entrées que vous ne contrôlez pas. Les valeurs par défaut sécurisées dans PHP moderne (7.0+) désactivent déjà le chargement des entités externes, donc la règle est simple :

  • N'utilisez pas LIBXML_NOENT ni LIBXML_DTDLOAD lors de l'analyse de XML non fiable.
  • Sur PHP < 8.0, vous pouvez également appeler libxml_disable_entity_loader(true) comme protection supplémentaire. Voir libxml_disable_entity_loader() pour les détails (la fonction est dépréciée en 8.0+ car le chargement est désactivé par défaut).

Valider des documents XML

libxml peut valider un document par rapport à une DTD ou un schéma XSD. DOMDocument::schemaValidate() est la méthode la plus directe, et les erreurs de validation passent par le même tampon :

<?php
libxml_use_internal_errors(true);

$doc = new DOMDocument();
if (!$doc->load('example.xml')) {
  echo "Could not load document." . PHP_EOL;
  exit;
}

if ($doc->schemaValidate('example.xsd')) {
  echo "The XML document is valid." . PHP_EOL;
} else {
  echo "Validation failed:" . PHP_EOL;
  foreach (libxml_get_errors() as $error) {
    echo "  line {$error->line}: " . trim($error->message) . PHP_EOL;
  }
  libxml_clear_errors();
}
?>

Pour les très grands fichiers, préférez le XMLReader en flux, qui valide au fil de la lecture sans charger l'intégralité du document en mémoire :

<?php
$reader = new XMLReader();
$reader->open('example.xml');
$reader->setSchema('example.xsd'); // attach the XSD before reading

$valid = true;
while ($reader->read()) {
  if (!$reader->isValid()) {
    $valid = false;
    break;
  }
}
$reader->close();

echo $valid ? "Document is valid." : "Document is not valid.";
?>

Manipuler des documents XML

Pour modifier un document, vous utilisez généralement DOM. L'exemple ci-dessous construit un document en mémoire (il fonctionne donc sans fichier externe), ajoute un nœud et affiche le résultat :

<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true; // pretty-print the output

// Build a root, then add a child element with text content.
$root = $doc->createElement('catalog');
$doc->appendChild($root);

$book = $doc->createElement('book', 'Learning PHP');
$book->setAttribute('id', '42');
$root->appendChild($book);

echo $doc->saveXML();
// <?xml version="1.0" encoding="UTF-8"?>
// <catalog>
//   <book id="42">Learning PHP</book>
// </catalog>
?>

Lors de la modification d'un fichier depuis le disque, chargez-le, localisez le nœud cible avec getElementsByTagName(), ajoutez à ce nœud (et non au document, qui ne peut contenir qu'un seul élément racine), puis sauvegardez-le avec save().

Quand utiliser cette extension ?

  • Lire des données de configuration ou de flux (RSS/Atom, réponses SOAP, sitemaps) — analysez avec SimpleXML, protégez avec les erreurs internes.
  • Valider des uploads — rejetez les documents qui échouent schemaValidate() avant de leur faire confiance.
  • Générer du XML pour une API ou un export — construisez-le avec DOM pour que les attributs et l'encodage soient gérés correctement.
  • Déboguer des échecs "XML invalide" — lisez libxml_get_errors() pour voir la ligne et la colonne exactes.

Conclusion

L'extension libxml est le fondement de la pile XML de PHP. Le schéma qui s'avère payant partout est : appeler libxml_use_internal_errors(true), analyser ou valider, puis inspecter libxml_get_errors() et libxml_clear_errors(). À partir de là, choisissez le bon outil — SimpleXML pour les lectures rapides, DOM pour l'édition, XMLReader pour les grands fichiers — et passez des options LIBXML_* pour contrôler le comportement de l'analyse. Gardez le chargement des entités désactivé pour les entrées non fiables et votre gestion du XML sera à la fois robuste et sécurisée.

Pratique

Pratique
Quelle est la contribution de l'extension PHP libxml ?
Quelle est la contribution de l'extension PHP libxml ?
Was this page helpful?