はじめに
前回までの記事で紹介してきた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 | $parser — xml_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() | クラスのメソッド一覧を取得 | 設定値ではなく構造情報を取得するという点で目的が異なる |
よくある落とし穴(注意点)
- 取得できるオプションの種類は限られている
xml_parser_get_option()で取得可能なのはXML_OPTION_CASE_FOLDING,XML_OPTION_TARGET_ENCODING,XML_OPTION_SKIP_TAGSTART,XML_OPTION_SKIP_WHITEの4種類のみです。それ以外の定数を指定すると警告が発生します。 xml_parser_set_option()と混同して値の変更を試みてしまう 関数名が似ているため、誤ってxml_parser_get_option()に3つ目の引数(新しい値)を渡そうとしてしまうミスがあります。値を変更したい場合は必ずxml_parser_set_option()を使いましょう。- 解放済みのパーサーに対して呼び出すとエラーになる
xml_parser_free()で解放した後のパーサーインスタンスに対してxml_parser_get_option()を呼び出すと、正しい結果は得られません。パーサーのライフサイクル管理には注意しましょう。 XML_OPTION_TARGET_ENCODINGの戻り値の型に注意する 多くのオプションは真偽値や整数を返しますが、XML_OPTION_TARGET_ENCODINGは文字列(エンコーディング名)を返します。型を意識した処理を行いましょう(例4を参照)。- 設定の取得だけでは解析結果には影響しない
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() との組み合わせや、複数のパーサーインスタンスが混在する複雑なシステムにおける設定の可視化・検証において、確実な動作を保証するための重要な役割を果たします。
