xml_set_end_namespace_decl_handler()
La fonction xml_set_end_namespace_decl_handler() est une fonction PHP intégrée qui définit un gestionnaire pour la fin des déclarations d'espaces de noms XML.
La fonction xml_set_end_namespace_decl_handler() est une fonction PHP intégrée qui enregistre un rappel défini par l'utilisateur à exécuter chaque fois que l'analyseur XML SAX atteint la fin d'un élément ayant déclaré un ou plusieurs espaces de noms XML. Elle est la contrepartie de fermeture de xml_set_start_namespace_decl_handler() : le gestionnaire de début se déclenche lorsqu'un préfixe d'espace de noms entre en portée, et ce gestionnaire de fin se déclenche lorsque ce préfixe sort de portée.
Cette fonction appartient à l'extension xml orientée événements (SAX) de PHP, qui lit un document de haut en bas et appelle vos gestionnaires au fur et à mesure qu'il rencontre chaque construction, plutôt que de construire un arbre en mémoire comme SimpleXML. Elle est particulièrement utile lorsque vous souhaitez suivre quels espaces de noms sont actifs pendant l'analyse — par exemple, pour maintenir une pile de préfixes en portée ou nettoyer l'état une fois qu'une section avec espace de noms se termine.
Quand l'utiliser
Une déclaration d'espace de noms est un attribut tel que xmlns:ns="http://example.com". Sa portée est l'élément sur lequel il apparaît et tous les descendants de cet élément. Utilisez le gestionnaire de fin d'espace de noms lorsque vous avez besoin de connaître le moment exact où cette portée se ferme — généralement pour retirer un préfixe d'une pile que vous avez construite dans le gestionnaire de début, en reproduisant la façon dont l'analyseur lui-même gère la portée.
Syntaxe
xml_set_end_namespace_decl_handler(XMLParser $parser, callable|false $handler): bool| Paramètre | Description |
|---|---|
$parser | L'analyseur XML, créé par xml_parser_create_ns() (recommandé) ou xml_parser_create(). |
$handler | Le rappel à exécuter pour chaque événement de fin d'espace de noms, ou false pour supprimer un gestionnaire précédemment défini. |
Valeur de retour : retourne true en cas de succès et false en cas d'échec (par exemple, si $parser n'est pas un analyseur valide).
Votre gestionnaire reçoit deux arguments :
function handler(XMLParser $parser, string $prefix): void$prefix est le préfixe d'espace de noms dont la portée se termine (une chaîne vide "" pour une déclaration xmlns="..." par défaut). Notez que, contrairement au gestionnaire de début, le gestionnaire de fin ne reçoit pas l'URI de l'espace de noms — uniquement le préfixe.
Exemples d'utilisation
Exemple : Définir un gestionnaire de fin de déclaration d'espace de noms
Cet exemple configure le gestionnaire et le déclenche en analysant une petite chaîne XML. Le gestionnaire est invoqué lors de xml_parse(), lorsque l'analyseur ferme l'élément qui a déclaré l'espace de noms.
Analyse XML avec un gestionnaire de fin de déclaration d'espace de noms
function handle_end_namespace_decl($parser, $prefix) {
echo "End of namespace prefix: $prefix\n";
}
$xml_parser = xml_parser_create_ns();
xml_set_end_namespace_decl_handler($xml_parser, "handle_end_namespace_decl");
$xml_data = '<?xml version="1.0"?><root xmlns:ns="http://example.com"><ns:child/></root>';
xml_parse($xml_parser, $xml_data, true);
xml_parser_free($xml_parser);Le préfixe ns est déclaré sur <root>, donc sa portée se termine lorsque </root> est atteint. Lorsque le gestionnaire se déclenche, il affiche le préfixe qui sort de portée :
End of namespace prefix: nsAttention : le déclenchement du gestionnaire de fin d'espace de noms est sensible à la version de
libexpat/PHP sous-jacente — sur certaines versions de PHP, le gestionnaire de début s'exécute mais pas le gestionnaire de fin. Testez toujours par rapport à votre environnement cible, et ne vous fiez jamais au gestionnaire de fin seul pour détecter un espace de noms ; associez-le au gestionnaire de début (ci-dessous) pour que votre état reste cohérent.
Exemple : Association des gestionnaires de début et de fin pour suivre la portée
Dans les analyseurs réels, le gestionnaire de fin est rarement utilisé seul. L'associer au gestionnaire de début vous permet de maintenir une pile des préfixes actuellement en portée. Le gestionnaire de début empile chaque préfixe lorsqu'il entre en portée ; le gestionnaire de fin le retire lorsque l'élément déclarant se ferme :
Suivi des préfixes d'espaces de noms en portée avec une pile
$activePrefixes = [];
function on_start_ns($parser, $prefix, $uri) {
global $activePrefixes;
$activePrefixes[] = $prefix;
echo "Enter '$prefix' -> $uri | active: " . implode(', ', $activePrefixes) . "\n";
}
function on_end_ns($parser, $prefix) {
global $activePrefixes;
array_pop($activePrefixes);
echo "Leave '$prefix' | active: " . implode(', ', $activePrefixes) . "\n";
}
$parser = xml_parser_create_ns();
xml_set_start_namespace_decl_handler($parser, "on_start_ns");
xml_set_end_namespace_decl_handler($parser, "on_end_ns");
$xml = '<?xml version="1.0"?>'
. '<a xmlns:x="urn:x"><b xmlns:y="urn:y"><c/></b></a>';
xml_parse($parser, $xml, true);
xml_parser_free($parser);Le préfixe x est déclaré sur <a> et y sur le <b> intérieur. Au fur et à mesure que les portées s'ouvrent et se ferment, la pile suit quels préfixes sont actuellement actifs. Les événements de fin se déclenchent dans l'ordre dernier entré, premier sorti — y (le plus intérieur) sort de portée avant x :
Enter 'x' -> urn:x | active: x
Enter 'y' -> urn:y | active: x, y
Leave 'y' | active: x
Leave 'x' | active: Ce schéma empilage/dépilement est l'utilisation canonique du gestionnaire de fin : il maintient votre vue des espaces de noms en portée alignée avec la propre gestion de portée de l'analyseur.
Pièges courants
- Utilisez
xml_parser_create_ns(). Les gestionnaires d'espaces de noms ne reçoivent des événements que lorsque l'analyseur est conscient des espaces de noms. Un analyseur créé avec le simplexml_parser_create()ne séparera pas les préfixes des URI. - Pas d'URI dans le rappel de fin. Si vous avez besoin de l'URI lorsque la portée se ferme, capturez-la dans le gestionnaire de début (indexée par préfixe) et recherchez-la ici.
- Définissez les gestionnaires avant d'analyser. Enregistrez le gestionnaire avant le premier appel à
xml_parse(); les gestionnaires définis en cours d'analyse manqueront les événements précédents. - Libérez l'analyseur. Appelez
xml_parser_free()lorsque vous avez terminé pour libérer les ressources, surtout dans les scripts de longue durée.
Conclusion
xml_set_end_namespace_decl_handler() permet à un analyseur SAX d'informer votre code exactement quand un préfixe d'espace de noms XML sort de portée. Combinée avec xml_set_start_namespace_decl_handler() et un analyseur conscient des espaces de noms provenant de xml_parser_create_ns(), elle vous offre un contrôle précis et à faible consommation de mémoire sur la portée des espaces de noms lors du traitement en flux de grands documents XML.