PHPでXMLの外部エンティティ宣言を駆使!xml_set_unparsed_entity_decl_handlerのサンプルコード集


xml_set_unparsed_entity_decl_handler 関数は、XML パーサーが外部エンティティ宣言に出くわした際に呼び出されるアンパースドエンティティ宣言ハンドラ関数を設定します。外部エンティティ宣言とは、XML ドキュメント内で参照される外部ファイルへのリンクを定義するものです。

構文

bool xml_set_unparsed_entity_decl_handler(XMLParser $parser, callable $handler);

パラメータ

  • $handler: 呼び出されるアンパースドエンティティ宣言ハンドラ関数。この関数は以下の引数を取ります。
    • $parser: ハンドラを呼び出す XML パーサー
    • $entity_name: 定義されるエンティティの名前
    • $base: 外部エンティティのシステム ID を解決するためのベース
    • $system_id: 外部エンティティのシステム ID
    • $public_id: 外部エンティティの公開 ID
    • $notation_name: このエンティティの表記の名前
  • $parser: XML パーサーリソース

戻り値

常に true を返します。

詳細

外部エンティティ宣言は、XML ドキュメント内で参照される外部ファイルへのリンクを定義します。これらのファイルは、XML ドキュメント自体に含まれないデータを含むことができます。

xml_set_unparsed_entity_decl_handler 関数は、外部エンティティ宣言に出くわした際に呼び出されるアンパースドエンティティ宣言ハンドラ関数を設定します。このハンドラ関数は、外部エンティティ宣言に関する情報を提供され、その情報に基づいて処理を行うことができます。

アンパースドエンティティ宣言ハンドラ関数は、以下のいずれかの方法で設定できます。

  • 閉鎖関数を渡す
  • オブジェクトとメソッド名を配列として渡す
  • 関数名を文字列として渡す

以下の例では、my_unparsed_entity_decl_handler 関数をアンパースドエンティティ宣言ハンドラ関数として設定します。

function my_unparsed_entity_decl_handler($parser, $entity_name, $base, $system_id, $public_id, $notation_name) {
    echo "Entity name: $entity_name\n";
    echo "System ID: $system_id\n";
    echo "Public ID: $public_id\n";
    echo "Notation name: $notation_name\n";
}

$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'my_unparsed_entity_decl_handler');

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse($parser, $xml_data);

この例を実行すると、以下の出力が得られます。

Entity name: my_entity
System ID: my_entity.xml
Public ID: 
Notation name: 
My text &my_entity;
  • 外部エンティティ宣言ハンドラ関数は、XML パーサーのパフォーマンスに影響を与える可能性があります。パフォーマンスが重要な場合は、この関数を慎重に使用してください。
  • アンパースドエンティティ宣言ハンドラ関数は、外部エンティティから読み込まれたデータにアクセスできます。このデータは、悪意のあるコードを含む可能性があることに注意してください。


function my_unparsed_entity_decl_handler($parser, $entity_name, $base, $system_id, $public_id, $notation_name) {
    echo "Entity name: $entity_name\n";
    echo "System ID: $system_id\n";
    echo "Public ID: $public_id\n";
    echo "Notation name: $notation_name\n";
}

$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'my_unparsed_entity_decl_handler');

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse($parser, $xml_data);

例 2: 外部エンティティをファイルに保存する

この例では、xml_set_unparsed_entity_decl_handler 関数を使用して、外部エンティティをファイルに保存するアンパースドエンティティ宣言ハンドラ関数を設定します。

function my_unparsed_entity_decl_handler($parser, $entity_name, $base, $system_id, $public_id, $notation_name) {
    $filename = $entity_name . '.xml';
    $file = fopen($filename, 'w');
    fwrite($file, file_get_contents($system_id));
    fclose($file);
}

$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'my_unparsed_entity_decl_handler');

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse($parser, $xml_data);

例 3: 外部エンティティを解析する

function my_unparsed_entity_decl_handler($parser, $entity_name, $base, $system_id, $public_id, $notation_name) {
    $parser2 = xml_parser_create();
    xml_set_element_handler($parser2, 'my_start_element_handler', 'my_end_element_handler');
    xml_set_character_data_handler($parser2, 'my_character_data_handler');

    $xml_data = file_get_contents($system_id);
    xml_parse($parser2, $xml_data);
}

function my_start_element_handler($parser, $name, $attrs) {
    echo "<$name";
    foreach ($attrs as $key => $value) {
        echo " $key=\"$value\"";
    }
    echo ">";
}

function my_end_element_handler($parser, $name) {
    echo "</$name>";
}

function my_character_data_handler($parser, $data) {
    echo $data;
}

$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'my_unparsed_entity_decl_handler');

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse($parser, $xml_data);

これらの例は、xml_set_unparsed_entity_decl_handler 関数の基本的な使用方法を示しています。この関数は、さまざまな目的に使用できます。ニーズに合わせてカスタマイズしてください。

  • 外部エンティティ宣言ハンドラ関数は、XML パーサーのパフォーマンスに影響を与える可能性があります。パフォーマンスが重要な場合は、この関数を慎重に使用
  • 外部エンティティ宣言ハンドラ関数は、外部エンティティから読み込まれたデータにアクセスできます。このデータは、悪意のあるコードを含む可能性があることに注意してください。


  • XML パーサーのパフォーマンスに影響を与える可能性がある
  • 外部エンティティを処理できない
  • 外部エンティティ宣言に関する情報しか提供されない

これらの制限を克服するために、xml_set_unparsed_entity_decl_handler 関数の代替方法がいくつかあります。

entity_decl オプションを使用する

xml_parse 関数の entity_decl オプションを使用すると、外部エンティティ宣言に関する情報を取得できます。このオプションは、xml_set_unparsed_entity_decl_handler 関数よりも柔軟性に優れています。

$parser = xml_parser_create();
xml_parse_set_option($parser, XML_OPTION_CASE_FOLDING, true);
xml_parse_set_option($parser, XML_OPTION_DTD, true);
xml_parse_set_option($parser, XML_OPTION_ENTITY, true);
xml_parse_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
xml_parse_set_option($parser, XML_OPTION_EXTERNAL_DTD, true);
xml_parse_set_option($parser, XML_OPTION_READ_EXTERNAL, true);
xml_parse_set_option($parser, XML_OPTION_STOP_ON_ERROR, true);
xml_parse_set_option($parser, XML_OPTION_NO_ERROR, false);
xml_parse_set_option($parser, XML_OPTION_WARN_ON_ERROR, true);

xml_parse_set_option($parser, XML_OPTION_ENTITY_DECL, 1);

function my_entity_decl_handler($parser, $entity_name, $value, $base, $system_id, $public_id, $notation_name) {
    // ...
}

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse($parser, $xml_data);

xml_parse_entities 関数を使用する

xml_parse_entities 関数を使用して、外部エンティティを解析できます。この関数は、xml_set_unparsed_entity_decl_handler 関数よりも強力ですが、より複雑でもあります。

function my_entity_handler($parser, $name, $value) {
    // ...
}

$xml_data = '<xml><!ENTITY my_entity SYSTEM "my_entity.xml">My text &my_entity;</xml>';
xml_parse_entities($xml_data, 'UTF-8', 'my_entity_handler');

サードパーティ製ライブラリを使用する

xml_set_unparsed_entity_decl_handler 関数の代替となるサードパーティ製ライブラリがいくつかあります。これらのライブラリは、より多くの機能と柔軟性を提供する場合があります。

xml_set_unparsed_entity_decl_handler 関数は、外部エンティティ宣言を処理するための基本的な方法を提供します。しかし、より多くの機能と柔軟性を必要とする場合は、代替方法を検討する必要があります。

  • 外部エンティティから読み込まれたデータは、悪意のあるコードを含む可能性があることに注意してください。
  • 上記の例は、説明のみを目的としています。実際の使用前に必ずドキュメントを確認してください。