スキップしてメイン コンテンツに移動

投稿

ラベル(XMLReader)が付いた投稿を表示しています

PHPのXMLReaderを使ったXMLの読み込み

はじめに PHPでXMLを読み込むには、通常はSimpleXMLElementを使えば十分です。 ただし、XMLが巨大でメモリを節約して処理する必要がある場合は、XMLのパーサーであるXMLReaderを使って処理する方法があります。 XMLReaderを使って読み込む際はXMLの構造をどうとらえるかによって、プログラムの書き方が変わるのと、毎回読み込みの方法をプログラムしなければならないのが欠点です。 今回は下記のサンプルXMLのproduct部分を読み込むXMLReaderのプログラムのサンプルを、XMLReaderの機能紹介も兼ねて、いくつか示します。 <?xml version="1.0" encoding="UTF-8"?> <products> <date type="1">20200414</date> <product> <maker>AMD</maker> <name>Ryzen 3400G</name> </product> <product> <maker>Intel</maker> <name>Core i9 9900K</name> </product> </products> サンプルプログラムでは、下記のPHPの配列形式を取得することを目標にします。 実際の用途ではXMLReaderを使ってXMLを読み込むと同時に、CSVファイルに出力するなどといった処理が考えられます。 この場合、メモリはXMLReader部分と、読み込み途中で一時的に保持しているデータのみで利用されるので、メモリの使用量は最低限に抑えることができます。 [ [ "maker"=> "AMD", "name"=> "Ryzen

PHPのXMLReaderで発生したエラーをExceptionとしてキャッチする方法

PHPのXMLReaderの内部で発生したエラーは、Exceptionではないためtry~catchブロックで捕まえることができません。 Exceptionとして捕まえるためには、set_error_handlerを使って、自前でエラーをExceptionに変換して投げる必要があります。 下記のコードで実現できます。 <?php // operationにエラーを発生させる可能性のある処理ブロックを渡す。 function caputureNativeErrorAndThrowIt(callable $operation) { $errorReportingLevel = error_reporting(E_ALL); set_error_handler(function( int $serverity, string $message, string $file, int $line ): void{ throw new \ErrorException($message, 0, $serverity, $file, $line); }); try { $operation(); } finally { restore_error_handler(); error_reporting($errorReportingLevel); } } // 下記はcaputureNativeErrorAndThrowIt関数をXMLReaderで使用した場合の例です。 $path = 'path_to_invalid_xml_file'; $reader = new \XMLReader(); $reader->open($path); caputureNativeErrorAndThrowIt(function() use($reader){ try { while($reader->read()){ // do something } } finally{ $reader->close()