[PHP]xml_parser_get_optionとは?XMLパーサーの現在の設定値を取得する方法を徹底解説

PHP

はじめに

前回までの記事で紹介してきたXMLパーサー関連の関数の中には、xml_parser_set_option() を使ってパーサーの挙動をカスタマイズする例が何度か登場しました(大文字小文字の変換制御、出力エンコーディングの指定など)。今回紹介する xml_parser_get_option() は、その名の通り設定した値を後から取得するための、set側と対になる関数です。

xml_parser_get_option() は、単体で目立つ機会は少ないものの、「このパーサーインスタンスは現在どのような設定になっているか」をプログラム的に確認したい場合に役立ちます。ライブラリやフレームワークの内部で複数箇所からパーサーが操作される可能性がある場合、現在の設定状態を検証するデバッグ用途や、条件分岐のための判定に活用できます。本記事では基本的な使い方から実践的な活用例まで詳しく解説します。


関数概要

項目内容
関数名xml_parser_get_option()
所属拡張XML Parser拡張(Expatベース、標準で有効)
シグネチャxml_parser_get_option(XMLParser $parser, int $option): string|int|bool
引数1$parserxml_parser_create()等で生成したパーサーインスタンス
引数2$option — 取得したいオプションの定数(XML_OPTION_*
戻り値現在のオプション設定値
対応バージョンPHP 4以降(PHP 8.0以降は引数の型がXMLParserオブジェクトに変更)
対になる関数xml_parser_set_option()
取得可能なオプションXML_OPTION_CASE_FOLDING, XML_OPTION_TARGET_ENCODING, XML_OPTION_SKIP_TAGSTART, XML_OPTION_SKIP_WHITE

設定と取得の関係性(イメージ図)

  xml_parser_create()
        │
        ▼
  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false)
        │  設定を書き込む
        ▼
  ┌─────────────────────┐
  │ パーサー内部の設定状態    │
  │ CASE_FOLDING: false     │
  │ TARGET_ENCODING: UTF-8  │
  │ SKIP_WHITE: true        │
  └──────────┬──────────┘
             │
             ▼
  xml_parser_get_option($parser, XML_OPTION_CASE_FOLDING)
        │  設定を読み出す
        ▼
      false  ← ★この記事の対象が返す値

ポイントは、xml_parser_get_option()パーサーインスタンスの「現在の」状態を確認するための読み取り専用の窓口であるという点です。設定を変更する xml_parser_set_option() とは役割が明確に分かれています。


実践サンプル7選

例1:基本的な使い方

<?php

class BasicOptionGetter
{
    public function checkCaseFolding(XMLParser $parser): bool
    {
        // 現在のcase folding設定を取得する
        return (bool) xml_parser_get_option($parser, XML_OPTION_CASE_FOLDING);
    }
}

$parser = xml_parser_create();
$getter = new BasicOptionGetter();
var_dump($getter->checkCaseFolding($parser)); // true (デフォルトは有効)

xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
var_dump($getter->checkCaseFolding($parser)); // false
xml_parser_free($parser);

例2:現在の全設定をまとめて確認するデバッグヘルパー

<?php

class ParserOptionInspector
{
    /**
     * 主要な設定オプションをまとめて取得し、
     * デバッグ時に一覧表示できるようにする
     */
    public function inspectAll(XMLParser $parser): array
    {
        return [
            'case_folding'     => xml_parser_get_option($parser, XML_OPTION_CASE_FOLDING),
            'target_encoding'  => xml_parser_get_option($parser, XML_OPTION_TARGET_ENCODING),
            'skip_tagstart'    => xml_parser_get_option($parser, XML_OPTION_SKIP_TAGSTART),
            'skip_white'       => xml_parser_get_option($parser, XML_OPTION_SKIP_WHITE),
        ];
    }
}

$parser = xml_parser_create('UTF-8');
$inspector = new ParserOptionInspector();
print_r($inspector->inspectAll($parser));
xml_parser_free($parser);

例3:設定変更が正しく反映されたかを検証するテストヘルパー

<?php

class OptionChangeVerifier
{
    /**
     * xml_parser_set_option()の呼び出し前後で、
     * 実際に設定が反映されたかをxml_parser_get_option()で検証する
     */
    public function verifyChange(XMLParser $parser, int $option, mixed $newValue): bool
    {
        $before = xml_parser_get_option($parser, $option);
        xml_parser_set_option($parser, $option, $newValue);
        $after = xml_parser_get_option($parser, $option);

        return $before !== $after;
    }
}

$parser = xml_parser_create();
$verifier = new OptionChangeVerifier();
var_dump($verifier->verifyChange($parser, XML_OPTION_CASE_FOLDING, false)); // true(変更された)
xml_parser_free($parser);

例4:現在の設定に応じて後続処理の挙動を分岐するクラス

<?php

class EncodingAwareResultFormatter
{
    /**
     * パーサーのターゲットエンコーディング設定を確認し、
     * それに応じて後続の文字列処理を分岐する
     */
    public function formatValue(XMLParser $parser, string $value): string
    {
        $encoding = xml_parser_get_option($parser, XML_OPTION_TARGET_ENCODING);

        if ($encoding !== 'UTF-8') {
            // UTF-8以外の場合は変換してから返す
            return mb_convert_encoding($value, 'UTF-8', $encoding);
        }

        return $value;
    }
}

$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'ISO-8859-1');
$formatter = new EncodingAwareResultFormatter();
echo $formatter->formatValue($parser, "caf\xe9") . PHP_EOL;
xml_parser_free($parser);

例5:共有パーサーファクトリーの設定内容を監査するツール

<?php

class ParserConfigurationAuditor
{
    /**
     * 複数箇所から生成されるパーサーの設定が
     * プロジェクトの規約通りになっているかを監査する
     */
    public function audit(XMLParser $parser, array $expectedOptions): array
    {
        $violations = [];

        foreach ($expectedOptions as $optionName => $expectedValue) {
            $actualValue = xml_parser_get_option($parser, $optionName);
            if ($actualValue !== $expectedValue) {
                $violations[] = "設定不一致: 期待値={$expectedValue}, 実際={$actualValue}";
            }
        }

        return $violations;
    }
}

$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, false);

$auditor = new ParserConfigurationAuditor();
$violations = $auditor->audit($parser, [XML_OPTION_SKIP_WHITE => true]);
print_r($violations);
xml_parser_free($parser);

例6:設定をスナップショットとして保存し、後で復元するクラス

<?php

class ParserOptionSnapshot
{
    private array $snapshot = [];

    /**
     * 現在の設定を保存しておき、
     * 一時的に変更した後で元の状態に戻せるようにする
     */
    public function save(XMLParser $parser): void
    {
        $this->snapshot = [
            XML_OPTION_CASE_FOLDING => xml_parser_get_option($parser, XML_OPTION_CASE_FOLDING),
            XML_OPTION_SKIP_WHITE   => xml_parser_get_option($parser, XML_OPTION_SKIP_WHITE),
        ];
    }

    public function restore(XMLParser $parser): void
    {
        foreach ($this->snapshot as $option => $value) {
            xml_parser_set_option($parser, $option, $value);
        }
    }
}

$parser = xml_parser_create();
$snapshot = new ParserOptionSnapshot();
$snapshot->save($parser);

xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); // 一時的に変更
// ...何らかの処理...
$snapshot->restore($parser); // 元の設定に戻す

xml_parser_free($parser);

例7:複数パーサーの設定差分を比較するデバッグツール

<?php

class ParserOptionDiffer
{
    /**
     * 2つのパーサーインスタンス間で
     * 設定に差異がないかを比較する
     */
    public function diff(XMLParser $parserA, XMLParser $parserB): array
    {
        $options = [XML_OPTION_CASE_FOLDING, XML_OPTION_TARGET_ENCODING, XML_OPTION_SKIP_WHITE];
        $differences = [];

        foreach ($options as $option) {
            $valueA = xml_parser_get_option($parserA, $option);
            $valueB = xml_parser_get_option($parserB, $option);

            if ($valueA !== $valueB) {
                $differences[$option] = ['a' => $valueA, 'b' => $valueB];
            }
        }

        return $differences;
    }
}

$parserA = xml_parser_create('UTF-8');
$parserB = xml_parser_create('ISO-8859-1');

$differ = new ParserOptionDiffer();
print_r($differ->diff($parserA, $parserB));

xml_parser_free($parserA);
xml_parser_free($parserB);

関連関数との比較

関数役割xml_parser_get_optionとの違い
xml_parser_get_option()パーサーの現在の設定値を取得本記事の対象。読み取り専用の窓口
xml_parser_set_option()パーサーの設定値を変更する設定を書き込む側の、対になる関数
xml_parser_create()パーサーインスタンスを生成生成時点ではデフォルトの設定が適用されている
ini_get()PHPの設定値(php.iniなど)を取得対象がXMLパーサー個別の設定ではなく、PHP全体の設定である点が異なる
get_class_methods()クラスのメソッド一覧を取得設定値ではなく構造情報を取得するという点で目的が異なる

よくある落とし穴(注意点)

  1. 取得できるオプションの種類は限られている xml_parser_get_option() で取得可能なのは XML_OPTION_CASE_FOLDING, XML_OPTION_TARGET_ENCODING, XML_OPTION_SKIP_TAGSTART, XML_OPTION_SKIP_WHITE の4種類のみです。それ以外の定数を指定すると警告が発生します。
  2. xml_parser_set_option() と混同して値の変更を試みてしまう 関数名が似ているため、誤って xml_parser_get_option() に3つ目の引数(新しい値)を渡そうとしてしまうミスがあります。値を変更したい場合は必ず xml_parser_set_option() を使いましょう。
  3. 解放済みのパーサーに対して呼び出すとエラーになる xml_parser_free() で解放した後のパーサーインスタンスに対して xml_parser_get_option() を呼び出すと、正しい結果は得られません。パーサーのライフサイクル管理には注意しましょう。
  4. XML_OPTION_TARGET_ENCODING の戻り値の型に注意する 多くのオプションは真偽値や整数を返しますが、XML_OPTION_TARGET_ENCODING は文字列(エンコーディング名)を返します。型を意識した処理を行いましょう(例4を参照)。
  5. 設定の取得だけでは解析結果には影響しない xml_parser_get_option() はあくまで現在の設定を「確認」するだけの関数であり、この呼び出し自体がパーサーの挙動に何らかの影響を与えることはありません。設定を変更したい場合は必ず xml_parser_set_option() を別途呼び出す必要があります。

まとめ

観点まとめ
何をする関数かXMLパーサーインスタンスの現在のオプション設定値を取得する
主な用途デバッグ時の設定確認、設定変更の検証、複数パーサー間の設定比較
対になる関数xml_parser_set_option()(設定を変更する)
取得可能なオプションCASE_FOLDING, TARGET_ENCODING, SKIP_TAGSTART, SKIP_WHITEの4種類
注意点取得可能なオプションの限定性、set関数との混同、解放済みパーサーへの誤用

xml_parser_get_option() は、単体では地味な存在ですが、xml_parser_set_option() との組み合わせや、複数のパーサーインスタンスが混在する複雑なシステムにおける設定の可視化・検証において、確実な動作を保証するための重要な役割を果たします。

タイトルとURLをコピーしました