現在の位置: ホーム> 最新記事一覧> XML_PARSEを使用して非同期リクエストでXMLデータを処理することに関するよくある質問

XML_PARSEを使用して非同期リクエストでXMLデータを処理することに関するよくある質問

M66 2025-05-12

PHP開発では、特に非同期リクエスト(AjaxやCurlを使用して非同期に取得するなど)を作成する場合、XML形式でデータを受信し、 XML_Parseで解析しようとすることがあります。ただし、多くの開発者は、実際のアプリケーションで、 XML_PARSEが常に期待どおりに機能するとは限らないことを発見しており、エラーを報告したり、空のデータを返したりすることさえあります。それで、なぜこれが起こっているのですか?

この記事では、 XML_PARSEを使用して非同期要求でXMLデータを処理するための一般的な問題とソリューションを分析します。

1。XML_PARSE基本的な使用法のレビュー

PHPでは、 XML_PARSEはイベントベースの解析を介してXMLを処理します。これは通常、 XML_PARSER_CREATEXML_SET_ELEMENT_HANDLER 、およびXML_PARSE自体で使用されます。例えば:

 $xml_parser = xml_parser_create();

xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

$data = file_get_contents("https://m66.net/api/data.xml");

if (!xml_parse($xml_parser, $data, true)) {
    die(sprintf("XML Error: %s at line %d",
        xml_error_string(xml_get_error_code($xml_parser)),
        xml_get_current_line_number($xml_parser)));
}

xml_parser_free($xml_parser);

同期環境では、このコードはうまく機能しますが、多くの場合、非同期呼び出しで発生します。

2。非同期要求の一般的な問題

1。XMLデータは完全には返されません

非同期リクエストは、データを完全に返信せずに処理を開始することが多く、XML文字列がXML_PARSEに渡され、不完全で解析障害が発生します。

解決:

非同期応答を処理するときは、データの整合性を確保し、コールバック関数を使用するなど、必要に応じてキャッシュまたは遅延処理メカニズムを使用します。

 function onXmlDataReceived($data) {
    if (strpos($data, '</root>') === false) {
        // XML たぶん完全に返されません
        return;
    }
    
    $parser = xml_parser_create();
    xml_parse($parser, $data, true);
    xml_parser_free($parser);
}

2。文字エンコーディングは一貫性がありません

多くのXMLインターフェイスは、UTF-8エンコードされたコンテンツを返しますが、PHPのデフォルトの内部エンコードはUTF-8ではない場合があります。エンコーディングが均一でない場合、 XML_PARSEはエラーを報告する場合があります。

解決:

パーサーを作成するときにエンコーディングを指定するか、XML自体が正しいエンコード形式を宣言していることを確認してください。

 $parser = xml_parser_create('UTF-8');

または、最初にエンコードと変換を行います:

 $data = mb_convert_encoding($data, 'UTF-8', 'auto');

3。非同期コールバックで失われたコンテキスト

Curlを使用したマルチスレッド(curl_multi_* functionファミリー)などの非同期リクエストでは、必要なパーサーまたはコンテキスト情報がコールバック関数に合格するのを忘れてXML_PARSEを適切に動作させない可能性があります。

エラーの例の例:

 curl_multi_add_handle($mh, $ch);

// コールバックでパーサーやその他のコンテキストを渡すのを忘れた

国家管理をカプセル化する正しい方法:

 class XmlParserContext {
    public $parser;
    public $data = '';

    public function __construct() {
        $this->parser = xml_parser_create();
        xml_set_element_handler($this->parser, "startElement", "endElement");
        xml_set_character_data_handler($this->parser, "characterData");
    }

    public function parse() {
        xml_parse($this->parser, $this->data, true);
        xml_parser_free($this->parser);
    }
}

4.エラー処理は不明です

XML_PARSE自体は例外をスローせず、ブール値のみを返し、 XML_Get_Error_CodeおよびXML_ERROR_STRINGを使用してエラーメッセージを取得する必要があります。エラーの不明確な処理は、問題を簡単に追跡するのが難しくなる可能性があります。

明確なエラーログを追加することをお勧めします:

 if (!xml_parse($parser, $data, true)) {
    error_log("XML Parse Error: " . xml_error_string(xml_get_error_code($parser)));
}

3。SimplexmlまたはDOMを使用して置き換えます

XML_PARSEは、下部のXMLを処理するための典型的な方法ですが、非同期リクエストでSimplexMLまたはDomDocumentを使用すると、より堅牢で簡潔になります。

 $xml = simplexml_load_string($data);

foreach ($xml->item as $item) {
    echo $item->title;
}

または:

 $dom = new DOMDocument();
$dom->loadXML($data);
$items = $dom->getElementsByTagName('item');

4。結論

XML_PARSEを使用して非同期要求でXMLデータを処理する場合、不完全なデータ、エンコードの不一致、コンテキストの喪失などの問題に遭遇することがよくあります。 XML_PARSEが必要な場合、データの整合性検出とコンテキスト管理を強化する必要があります。それ以外の場合は、 SimplexMLDomdocumentなどの高レベルのXML解析ツールを使用することをお勧めします。