現在の位置: ホーム> 最新記事一覧> XML_PARSEメモリは、マルチラインXMLデータを解析するときに発生する可能性のある漏れです

XML_PARSEメモリは、マルチラインXMLデータを解析するときに発生する可能性のある漏れです

M66 2025-04-26

PHPでXMLを解析する一般的な方法の1つは、 XML_PARSER_CREATE()およびXML_PARSE()などの関連関数を使用して、XML Data Rowをラインごとに使用することです。ただし、特に大きなファイルや複数の入力行を処理する場合、リソースのリリースや不適切な処理方法に注意を払わない場合、メモリリークを引き起こすのは簡単で、スクリプトのメモリ使用量が増加し、最終的にサーバーの例外やクラッシュさえ発生する可能性があります。

この記事では、問題の原因を簡単に紹介し、メモリリークを避けるための安全で推奨される方法を提供します。

質問の例

次のコードスニペットを検討してください。

 $parser = xml_parser_create();

$fp = fopen("https://m66.net/data.xml", "r");
while ($data = fgets($fp)) {
    xml_parse($parser, $data, feof($fp));
}
fclose($fp);
// パーサーリソースをリリースするのを忘れました

このコードでは、 XML_PARSE()は、データの各行が読み取られるようにリソースを継続的に割り当てます。 XML_PARSER_FREE($ PARSER)に電話してパーサーを解放することを忘れた場合、特に大規模または高頻度のXMLリクエストを処理する場合、プログラムが占めるメモリはリリースされません。問題はさらに深刻です。

正しい方法:タイムリーにリソースをリリースします

メモリリークを避けるために、最も直接的で必要なステップは、パーサーを必要としなくなった時間にXML_PARSER_FREE()を呼び出すことです。

 $parser = xml_parser_create();

// オプション:処理機能のセットアップ
xml_set_element_handler($parser, "startElement", "endElement");

$fp = fopen("https://m66.net/data.xml", "r");
while ($data = fgets($fp)) {
    if (!xml_parse($parser, $data, feof($fp))) {
        die(sprintf("XML 間違い:%s で %d わかりました",
            xml_error_string(xml_get_error_code($parser)),
            xml_get_current_line_number($parser)));
    }
}
fclose($fp);

// パーサーリソースを適切にリリースします
xml_parser_free($parser);

高度な提案

1.イベントコールバックを使用して、メモリをより効率的に管理します

パーサーのコールバック処理関数を設定して、ノード処理が完了し、使用されなくなった変数がリリースされた直後にデータが処理されるようにすることができます。

 function startElement($parser, $name, $attrs) {
    // スタートタグを処理します
}

function endElement($parser, $name) {
    // エンドタグの処理
}

xml_set_element_handler($parser, "startElement", "endElement");

2。各読み取りの長さを制限します

FGETS()を使用しない場合、 FREAD()を使用して、毎回読み取られるデータの量を制限して、一度に長いラインがあまりにも多くのメモリを占有しないようにします。

 while ($data = fread($fp, 4096)) {
    xml_parse($parser, $data, feof($fp));
}

3. XML_PARSEの代わりにXMLReaderを使用します

XMLReaderは、より近代的なプルシェマベースのXML解析方法です。パフォーマンスが高いだけでなく、より洗練されたメモリ管理もあります。これは、大量のデータボリュームを使用したXMLストリーム処理に適しています。

 $reader = new XMLReader();
$reader->open("https://m66.net/data.xml");

while ($reader->read()) {
    if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item') {
        // 対処する <item> ノード
    }
}
$reader->close();

要約します

XML_PARSEを使用してマルチラインXMLデータを処理する場合、メモリの漏れを避けるために、パーサーリソースを時間内にリリースすることを忘れないでください。より推奨されるアプローチは、パフォーマンスとメモリコントロールの点で優れているXMLReaderなどのより近代的な解析方法を使用することです。どの方法を使用しても、リソース管理の適切な感覚は、常にコードの堅牢性を確保するための鍵です。

この記事がPHPのXMLメモリの問題に対処するのに役立つことを願っています!