xml_set_element_handler()
La fonction xml_set_element_handler() définit des fonctions utilisateur comme gestionnaires des balises ouvrantes et fermantes d'un élément XML en PHP.
xml_set_element_handler() enregistre deux callbacks sur un analyseur XML : l'un qui se déclenche à chaque fois que l'analyseur rencontre une balise ouvrante (<book>) et l'autre qui se déclenche sur chaque balise fermante (</book>). Elle appartient au parseur Expat orienté événements de PHP — la famille xml_parser_* — et non à SimpleXML ou DOM. Là où SimpleXML charge l'intégralité du document dans un arbre en mémoire, Expat parcourt le document en flux et appelle vos gestionnaires au fil de la lecture, ce qui le rend particulièrement adapté aux fichiers volumineux que vous ne souhaitez pas charger en une seule fois.
Cette page couvre la signature de la fonction, les arguments exacts que reçoivent vos gestionnaires, un exemple complet et exécutable, ainsi que les pièges courants (repli en majuscules des noms de balises et la forme de callback méthode-objet).
Syntaxe
xml_set_element_handler(
XMLParser $parser,
callable $start_handler,
callable $end_handler
): bool| Paramètre | Description |
|---|---|
$parser | L'analyseur créé par xml_parser_create(). |
$start_handler | Appelé sur chaque balise ouvrante. Reçoit ($parser, $name, $attributes). |
$end_handler | Appelé sur chaque balise fermante. Reçoit ($parser, $name). |
La fonction retourne true en cas de succès et false en cas d'échec. Un callback peut être fourni sous forme de chaîne de nom de fonction ("startTag"), d'une closure, ou d'une paire objet-méthode ([$object, 'method']).
Ce que reçoivent les gestionnaires
- Gestionnaire de début —
$nameest le nom de la balise et$attributesest un tableau associatif des attributs de cette balise (['ID' => 'b1']). - Gestionnaire de fin — uniquement
$name, car les balises fermantes ne portent pas d'attributs.
Par défaut, Expat convertit les noms de balises et d'attributs en majuscules (
<book>arrive sous la formeBOOK). Comparez les noms sans tenir compte de la casse, ou désactivez cette conversion avecxml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Voirxml_parser_set_option().
Exemples d'utilisation
Exemple : Afficher l'arborescence des éléments
Ce script complet analyse une chaîne XML et utilise les gestionnaires de début/fin pour afficher un plan indenté du document, incluant les attributs de chaque balise.
<?php
$xml = '<?xml version="1.0"?>
<library>
<book id="b1">PHP Basics</book>
<book id="b2">Advanced XML</book>
</library>';
$depth = 0;
function startTag($parser, $name, $attrs) {
global $depth;
echo str_repeat(" ", $depth) . "START: $name";
foreach ($attrs as $key => $value) {
echo " ($key=\"$value\")";
}
echo "\n";
$depth++;
}
function endTag($parser, $name) {
global $depth;
$depth--;
echo str_repeat(" ", $depth) . "END: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startTag", "endTag");
if (!xml_parse($parser, $xml, true)) {
die(sprintf(
"XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);Résultat :
START: LIBRARY
START: BOOK (ID="b1")
END: BOOK
START: BOOK (ID="b2")
END: BOOK
END: LIBRARYRemarquez que library arrive sous la forme LIBRARY et id sous la forme ID : c'est la conversion en majuscules mentionnée ci-dessus. Le troisième argument de xml_parse() est défini à true pour indiquer à l'analyseur qu'il s'agit du dernier (et unique) bloc de données. Libérez toujours l'analyseur avec xml_parser_free() une fois terminé.
Exemple : Utiliser une méthode d'objet comme gestionnaire
Les gestionnaires n'ont pas à être des fonctions libres. Passer [$object, 'method'] vous permet de conserver l'état de l'analyse sur un objet plutôt que dans des variables globales — utile lorsque plusieurs gestionnaires doivent partager des données.
<?php
$xml = '<note><to>Tove</to><from>Jani</from></note>';
class TagCounter {
public int $open = 0;
public function onStart($parser, $name, $attrs) { $this->open++; }
public function onEnd($parser, $name) {}
}
$counter = new TagCounter();
$parser = xml_parser_create();
xml_set_element_handler($parser, [$counter, 'onStart'], [$counter, 'onEnd']);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
echo "Opening tags seen: {$counter->open}\n";Résultat :
Opening tags seen: 3Quand l'utiliser
Recourez aux gestionnaires Expat lorsque vous avez besoin d'un parcours en flux, à faible consommation mémoire du XML — grands flux de données, fichiers journaux ou sitemaps — ou lorsque vous ne vous intéressez qu'à quelques balises et ne souhaitez pas construire un arbre complet. Pour lire le texte à l'intérieur d'un élément (le PHP Basics dans <book>PHP Basics</book>), combinez ceci avec xml_set_character_data_handler(). Si vous préférez interroger un petit document avec un accès de type XPath, SimpleXML est plus simple. Pour un aperçu de chaque approche, consultez PHP XML Parsers.
Conclusion
xml_set_element_handler() relie des callbacks de balises ouvrantes et fermantes au parseur Expat orienté événements de PHP, vous permettant de réagir à la structure d'un document au fil de sa lecture. Retenez les trois essentiels : créez d'abord l'analyseur, tenez compte des noms de balises en majuscules, et libérez l'analyseur une fois terminé.