PHPのXMLパーサー(通常、 XML_PARSER_CREATE()やXML_PARSE( )などのExpatベースの機能を使用する場合、プログラムで複数回XML_PARSE()を複数回呼び出して、複数のXMLデータブロックを解析します。各解析の前にパーサーを適切にリセットまたは再作成しない場合、予期しない問題につながる可能性があります。これらの問題の理由とそれらを回避する方法を詳細に分析しましょう。
XMLパーサーは、現在解析中のノードの深さ、解析されたコンテンツバッファーなど、状態を内部的に維持します。同じパーサーインスタンスを使用して、それらの間でそれらをリセットまたは破壊することなく複数のXMLドキュメントを解析する場合、以前の文書によって左に残された状態は次の文書に影響を与える可能性があります。
例:
$xml1 = "<note><to>John</to></note>";
$xml2 = "<message><from>Jane</from></message>";
$parser = xml_parser_create();
// 最初の分析
xml_parse($parser, $xml1);
// 2番目のパーサーが使用されます
xml_parse($parser, $xml2); // 解析エラーを引き起こす可能性があります!
xml_parser_free($parser);
上記のコードでは、 XML2データを2度目に解析する場合、 $パーサーは、構文エラー、論理判断の例外、さらには直接障害につながる可能性のある最初の解析XML1のステータス情報を依然として保持します。
PHPのXMLパーサーを使用すると、XML_SET_ELEMENT_HANDLER()を介して開始要素とエンド要素のコールバック関数を設定できます。これらのコールバックは通常、特定の外部変数または状態に依存します。コンテキストまたは状態変数が複数の分割間で適切にクリーニングされていない場合、データの混乱を引き起こすのは簡単です。
例:
function startElement($parser, $name, $attrs) {
echo "タグを開始します: $name\n";
}
function endElement($parser, $name) {
echo "タグを終了します: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
$xml = "<user><name>テスト</name></user>";
xml_parse($parser, $xml);
// 次に、別のドキュメントを解析します
$xml2 = "<product><title>商品</title></product>";
xml_parse($parser, $xml2); // コールバックは不適切に処理される場合があります
$パーサーはリセットされていないため、コールバックまたは内部状態の結合が異常である可能性があり、その結果、論理処理が混乱します。
2つのXMLが異なるエンコーディングを使用する前後のドキュメント(たとえば、UTF-8、もう1つはISO-8859-1です)が、パーサーはまだ以前の設定を使用しており、再構成されていない場合、コードや解析の障害を引き起こす可能性があります。
$parser = xml_parser_create("UTF-8");
$xml1 = "<?xml version='1.0' encoding='UTF-8'?><data>こんにちは</data>";
$xml2 = "<?xml version='1.0' encoding='ISO-8859-1'?><data>Olá</data>";
xml_parse($parser, $xml1);
xml_parse($parser, $xml2); // コーディングの競合,エラーが報告される場合があります
上記の問題を回避するために、ベストプラクティスは、新しいXMLドキュメントが解析され、解析後にリソースを解放するたびに新しいパーサーインスタンスを作成することです。
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);
これにより、状態干渉、一貫性のないエンコード、コールバックの混乱などの問題が回避されます。
複数のXMLデータを処理するときは、パーサーを「クリーン」に保つことが重要です。パーサーを直接再利用することはリソースを節約できるように見えるかもしれませんが、結果として生じる州の汚染、コーディング紛争、その他の問題は努力する価値がないことがよくあります。最も安全な方法は、「一度使用し、一度構築し、解析した後に破壊する」ことです。
たとえば、XMLデータを頻繁に処理する必要があるインターフェイスを開発している場合:
関連タグ:
xml_parse