Lorsque vous utilisez l'analyse XML de PHP (généralement des fonctions basées sur les expatriés, telles que xml_parser_create () et xml_parse () ), nous appelons souvent xml_parse () plusieurs fois dans un programme pour analyser plusieurs blocs de données XML. Si nous ne réinitialisons pas ou ne recréons pas correctement l'analyseur avant chaque analyse, cela peut entraîner une série de problèmes inattendus. Analyons en détail les raisons de ces problèmes et comment les éviter.
L'analyseur XML conservera l'état en interne, comme la profondeur du nœud actuellement analysé, le tampon de contenu qui a été analysé, etc. Si vous utilisez la même instance d'analyseur pour analyser plusieurs documents XML sans les réinitialiser ou les détruire entre eux, l'état laissé par le document précédent peut affecter la analyse du document suivant.
Exemple:
$xml1 = "<note><to>John</to></note>";
$xml2 = "<message><from>Jane</from></message>";
$parser = xml_parser_create();
// Première analyse
xml_parse($parser, $xml1);
// Le deuxième analyseur est utilisé
xml_parse($parser, $xml2); // Peut provoquer des erreurs d'analyse!
xml_parser_free($parser);
Dans le code ci-dessus, lors de l'analyse des données XML2 pour la deuxième fois, $ Parser conserve toujours les informations d'état du premier analyse XML1 , ce qui peut entraîner des erreurs de syntaxe, des exceptions de jugement logique et même des échecs directs.
L'analyseur XML de PHP permet la définition de la fonction de rappel pour les éléments de démarrage et de fin via XML_SET_ELEMENT_HANDLER () . Ces rappels reposent généralement sur certaines variables ou états externes. Si les variables de contexte ou d'état ne sont pas correctement nettoyées entre plusieurs analyses, il est facile de provoquer une confusion des données.
Exemple:
function startElement($parser, $name, $attrs) {
echo "Tag de démarrage: $name\n";
}
function endElement($parser, $name) {
echo "Étiquette de fin: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
$xml = "<user><name>test</name></user>";
xml_parse($parser, $xml);
// Puis analyser un autre document
$xml2 = "<product><title>marchandises</title></product>";
xml_parse($parser, $xml2); // Le rappel peut être traité mal
Étant donné que $ analyser n'est pas réinitialisé, la liaison du rappel ou d'un état interne peut être anormale, entraînant une confusion dans le traitement logique.
Si les deux documents XML avant et après utilisent différents encodages (par exemple, l'un est UTF-8 et l'autre est ISO-8859-1), mais l'analyseur utilise toujours les paramètres précédents et n'a pas été reconfiguré, il peut également provoquer un code brouillé ou une panne d'analyse.
$parser = xml_parser_create("UTF-8");
$xml1 = "<?xml version='1.0' encoding='UTF-8'?><data>Bonjour</data>";
$xml2 = "<?xml version='1.0' encoding='ISO-8859-1'?><data>Olá</data>";
xml_parse($parser, $xml1);
xml_parse($parser, $xml2); // Conflit de codage,Une erreur peut être signalée
Pour éviter les problèmes ci-dessus, la meilleure pratique consiste à créer une nouvelle instance d'analyse chaque fois qu'un nouveau document XML est analysé et libérer des ressources après l'analyse.
function parseXml($xmlString) {
$parser = xml_parser_create("UTF-8");
xml_parse($parser, $xmlString, true);
xml_parser_free($parser);
}
$xml1 = "<note><to>John</to></note>";
$xml2 = "<message><from>Jane</from></message>";
parseXml($xml1);
parseXml($xml2);
Cela évite des problèmes tels que l'ingérence de l'État, le codage incohérent et la confusion de rappel.
Il est important de garder l'analyseur "propre" lors du traitement de plusieurs données XML. Bien que la réutilisation directe de l'analyseur puisse sembler économiser des ressources, la pollution de l'État qui en résulte, les conflits de codage et d'autres problèmes ne valent souvent pas les efforts. Le moyen le plus sûr est de "l'utiliser une fois, de le construire une fois et de le détruire après l'avoir analysé".
Si vous développez une interface qui doit traiter fréquemment les données XML, par exemple: