【PHP8.x】DOMEntityReference::C14NFile()メソッドの使い方
C14NFileメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
C14NFileメソッドは、DOMEntityReferenceオブジェクトが表すエンティティ参照ノードを、XML正規化(Canonical XML)のルールに従ってファイルに出力するメソッドです。XML正規化とは、XML文書の論理的な意味を保ったまま、空白の扱い、属性の順序、文字参照といった物理的な表現を標準的な形式に統一する処理のことです。このメソッドを使用することで、エンティティ参照ノードの内容を正規化し、指定したファイルパスへ保存できます。第一引数には出力先のファイルURIを指定します。さらに、オプションの引数を用いることで、排他的正規化の適用の有無、コメントノードを含めるかどうかの指定、あるいはXPathクエリや名前空間プレフィックスによる対象ノードの絞り込みといった、より詳細な制御が可能です。処理が成功した場合はファイルに書き込まれたバイト数を整数値で返し、失敗した場合は false を返します。この機能は、XMLデータのデジタル署名や、内容の同一性をバイトレベルで厳密に検証する際に特に重要となります。
構文(syntax)
1public DOMNode::C14NFile( 2 string $uri, 3 bool $exclusive = false, 4 bool $withComments = false, 5 ?array $xpath = null, 6 ?array $nsPrefixes = null 7): int|false
引数(parameters)
string $uri, bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null
- string $uri: 指定されたエンティティ参照のURI
- bool $exclusive = false: 署名対象の要素を排他的にするかどうか
- bool $withComments = false: コメントを含むかどうか
- ?array $xpath = null: XPath式による対象要素の絞り込み
- ?array $nsPrefixes = null: 名前空間プレフィックスのリスト
戻り値(return)
int|false
C14NFile メソッドは、エンティティ参照が標準化された形式で記述できた場合は整数、それ以外の場合は false を返します。
サンプルコード
DOMEntityReference::C14NFileでC14Nファイルを出力する
1<?php 2 3/** 4 * DOMEntityReference::C14NFile の使用例を示す関数。 5 * 6 * この関数は、DOMEntityReference ノードを Canonical XML (C14N) 形式でファイルに書き込みます。 7 * Canonical XML は、XML ドキュメントを一意な文字列表現に変換するための標準です。 8 * DOMEntityReference ノードを直接 C14N 化すると、通常は '&entityName;' という形式で出力されます。 9 * 10 * @return void 11 */ 12function demonstrateDomEntityReferenceC14NFile(): void 13{ 14 // 1. DOMDocument オブジェクトを作成します。 15 // エンティティ参照ノードを作成するために必要です。 16 $dom = new DOMDocument('1.0', 'UTF-8'); 17 18 // 2. DOMEntityReference ノードを作成します。 19 // DOMEntityReference は通常、XMLのDTD(文書型定義)内で定義されたエンティティ(例: )を 20 // 参照するノードですが、ここではそのノード自体をC14N化するデモンストレーションとして作成します。 21 $entityName = 'myEntity'; 22 $entityRef = $dom->createEntityReference($entityName); 23 24 // 3. C14N 化されたXMLを出力するファイルパスを準備します。 25 // システムの一時ディレクトリを使用し、一時的なファイルを作成します。 26 $outputFileName = 'output_c14n_entity.xml'; 27 $outputFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $outputFileName; 28 29 echo "C14Nファイルを '$outputFilePath' に書き込みます。\n"; 30 31 // 4. DOMEntityReference の C14NFile メソッドを呼び出し、C14N形式でファイルに書き込みます。 32 // 引数: 33 // $uri (string): 出力先のファイルURI。 34 // $exclusive (bool): 排他的なC14N化を行うか (false = 包括的, true = 排他的)。 35 // $withComments (bool): コメントを含めるか。 36 // (その他2つの引数 $xpath, $nsPrefixes はここではデフォルト値を使用) 37 // 戻り値は書き込まれたバイト数、または失敗した場合は false です。 38 $bytesWritten = $entityRef->C14NFile($outputFilePath, false, false); 39 40 if ($bytesWritten !== false) { 41 echo "C14Nファイルが正常に書き込まれました。書き込まれたバイト数: $bytesWritten\n"; 42 43 // 5. 生成されたファイルの内容を読み取り、コンソールに表示して確認します。 44 if (file_exists($outputFilePath)) { 45 $content = file_get_contents($outputFilePath); 46 echo "\n--- 生成された C14N ファイルの内容 ---\n"; 47 echo $content; 48 echo "\n----------------------------------------\n"; 49 echo "DOMEntityReference をC14N化すると、通常は '&{$entityName};' という形式で出力されます。\n"; 50 } 51 } else { 52 echo "C14Nファイルの書き込みに失敗しました。\n"; 53 } 54 55 // 6. 一時的に作成したファイルをクリーンアップします。 56 // 初心者の方が内容を確認しやすいように、この行はコメントアウトしています。 57 // 必要であればコメントを解除してファイルを削除してください。 58 // if (file_exists($outputFilePath)) { 59 // unlink($outputFilePath); 60 // echo "一時ファイルを削除しました: $outputFilePath\n"; 61 // } 62} 63 64// 上記の関数を実行し、DOMEntityReference::C14NFile の動作をデモンストレーションします。 65demonstrateDomEntityReferenceC14NFile(); 66 67?>
DOMEntityReference::C14NFile メソッドは、PHPのDOM拡張機能において、XML文書内のエンティティ参照ノードをCanonical XML (C14N) 形式で指定のファイルに書き出すために使用されます。C14Nとは、XMLドキュメントを一意な文字列表現に変換するための標準規格です。
サンプルコードは、DOMDocument オブジェクトで作成した DOMEntityReference ノード(例えば &myEntity;)を対象に、この C14NFile メソッドの動作を示しています。$uri 引数には出力先のファイルパスを指定します。$exclusive と $withComments 引数は、C14N化の際に排他的な正規化を行うか、コメントを含めるかといった詳細な挙動を制御するオプションです。
このメソッドが成功すると、ファイルに書き込まれたバイト数が整数値として返され、処理に失敗した場合はブール値の false が返されます。DOMEntityReference ノードをC14N化すると、通常 &エンティティ名; という簡潔な形式で出力されることが、サンプルコードの実行結果で確認できます。この機能は、XML文書中の特定のエンティティ参照部分の標準化された表現をファイルとして保存したい場合に役立ちます。
DOMEntityReference::C14NFileは、XMLのエンティティ参照ノードをCanonical XML形式で指定ファイルに書き出すメソッドです。このメソッドは、エンティティ参照ノード自体をC14N化するため、通常は&エンティティ名;という形式でファイルに出力されることを理解してください。
引数$uriには出力先のファイルパスを正確に指定し、PHPがそのパスに書き込み権限を持っていることを確認してください。メソッドの戻り値は、書き込まれたバイト数、または失敗時にfalseを返します。そのため、必ずfalseでないかを確認し、適切なエラーハンドリングを行うことが重要です。
サンプルコードでは一時ファイルを削除していませんが、実際のシステム開発では、作成した一時ファイルは不要になった時点で確実に削除し、システムリソースを適切に管理するようにしてください。
PHP XMLを正規化してファイル保存する
1<?php 2 3/** 4 * PHPのDOMNode::C14NFileメソッド(DOMDocumentクラスで利用)を使用して、 5 * XMLデータをCanonical XML形式でファイルに書き出すサンプルコード。 6 * キーワード「php cp」に関連する、XMLデータのファイルへの出力機能を示します。 7 * 8 * @param string $xmlString 元となるXMLデータ文字列。 9 * @param string $outputFilePath 出力先のファイルパス。 10 * @return bool ファイルへの書き出しが成功した場合はtrue、失敗した場合はfalse。 11 */ 12function createCanonicalXmlFile(string $xmlString, string $outputFilePath): bool 13{ 14 // DOMDocumentオブジェクトを初期化 15 $dom = new DOMDocument(); 16 // 厳密なエラーチェックを無効にしてXMLをロード(無効なXMLによる警告の発生を抑制するため) 17 // loadXML()はXMLの解析に成功した場合にtrue、失敗した場合にfalseを返します。 18 if (!@$dom->loadXML($xmlString)) { 19 echo "Error: Failed to load XML string. Please check if the XML is well-formed.\n"; 20 return false; 21 } 22 23 // Canonical XML (C14N) をファイルに出力します。 24 // C14NFileはDOMNodeクラスのメソッドです。DOMDocumentクラスはDOMNodeを継承しているため、このメソッドを利用できます。 25 // このメソッドは、XMLの正規化された形式を新しいファイルに書き出します。 26 // 27 // 引数: 28 // $uri: 出力先のファイルパス。 29 // $exclusive: 排他的C14N (Exclusive Canonical XML) を使用するかどうか (true/false)。 30 // 通常はfalseで、包括的C14Nが使用されます。 31 // $withComments: 元のXMLに含まれるコメントを正規化された出力に含めるかどうか (true/false)。 32 // 通常はfalseで、コメントは削除されます。 33 // $xpath: 正規化する特定のノードセットを指定するXPath式(nullの場合はドキュメント全体)。 34 // $nsPrefixes: 正規化に関連する名前空間プレフィックスの配列(nullの場合は全て)。 35 // 36 // 戻り値: 成功した場合はファイルに書き込まれたバイト数、失敗した場合はfalse。 37 $bytesWritten = $dom->C14NFile($outputFilePath, false, false, null, null); 38 39 if ($bytesWritten !== false) { 40 echo "Canonical XML successfully written to: " . $outputFilePath . " (" . $bytesWritten . " bytes)\n"; 41 return true; 42 } else { 43 echo "Error: Failed to write Canonical XML to " . $outputFilePath . "\n"; 44 return false; 45 } 46} 47 48// --- サンプルコードの実行例 --- 49 50// サンプルXMLデータ 51// このXMLがCanonical XML形式に変換されてファイルに出力されます。 52// Canonical XMLの主な特徴: 53// - 属性は常にアルファベット順にソートされる(例: attr2, attr1 -> attr1, attr2)。 54// - 不要な空白や改行が正規化される(例: <child>Hello World!</child> -> <child>Hello World!</child>)。 55// - XML宣言 (<?xml ...?>) や内部コメントは、デフォルト($withComments=false)では削除されます。 56// - 実体参照は展開される(例: & -> &)。 57$sampleXml = <<<XML 58<?xml version="1.0" encoding="UTF-8"?> 59<root attr2="value2" attr1="value1"> 60 <child> 61 Hello World! & XML. 62 </child> 63 <!-- これは無視されるコメントです --> 64 <data emptyAttribute=""/> 65</root> 66XML; 67 68// 出力ファイルパスの指定 69// スクリプトが実行されるディレクトリに 'canonical_output.xml' という名前でファイルが作成されます。 70$outputFile = __DIR__ . '/canonical_output.xml'; 71 72// 関数を実行し、XMLデータを正規化してファイルに書き出します 73if (createCanonicalXmlFile($sampleXml, $outputFile)) { 74 // 成功した場合、生成されたファイルの内容を表示して確認します 75 echo "\n--- Content of " . $outputFile . " ---\n"; 76 // ファイルが実際に作成されたことを確認してから内容を読み込みます 77 if (file_exists($outputFile)) { 78 echo file_get_contents($outputFile); 79 } else { 80 echo "File not found at: " . $outputFile . " after write attempt.\n"; 81 } 82 echo "\n-------------------------------------\n"; 83} else { 84 echo "Processing failed: Canonical XML file could not be created.\n"; 85} 86 87// 注意: このスクリプトは 'canonical_output.xml' ファイルを作成します。 88// 不要な場合は、スクリプト実行後に手動でファイルを削除してください。 89// 例: unlink($outputFile);
PHP 8で提供されるDOMDocument::C14NFileメソッドは、XMLデータをCanonical XML形式に正規化し、その結果を指定したファイルに書き出すための機能です。これは「php cp」のようにXMLの内容をファイルに出力する用途で利用でき、特にXMLの構造や内容を標準的な形式で統一したい場合に役立ちます。
このメソッドはDOMDocumentオブジェクトから呼び出され、XMLドキュメント全体または指定した一部を正規化します。最初の引数$uriには、正規化されたXMLデータを出力するファイルのパスを指定します。$exclusiveは排他的Canonical XMLを使用するかどうかを設定し、通常はfalseで包括的な形式が適用されます。$withCommentsは、元のXMLに含まれるコメントを正規化後の出力に含めるかを決定し、falseに設定するとコメントは削除されます。残りの$xpathと$nsPrefixes引数は、XMLドキュメントの一部のみを正規化したい場合や、名前空間の扱いを詳細に制御したい場合に利用します。
処理が成功すると、このメソッドはファイルに書き込まれたバイト数を整数値で返します。万が一、ファイルの書き込みに失敗した場合はfalseが返されるため、戻り値を確認することで処理の成否を判断できます。これにより、XMLの内容を一貫性のある形でファイルに保存し、比較や署名などの処理に利用できるようになります。
C14NFileメソッドは、XMLを正規化するため、元のXMLデータの属性順序や空白、コメントなどが変更される点にご注意ください。出力される形式が期待通りか確認するため、引数$exclusiveや$withCommentsを適切に設定してください。
このメソッドは成功した場合に書き込まれたバイト数、失敗した場合にfalseを返します。処理の成否を判断するため、戻り値は!== falseのような厳密な比較を用いて必ず確認し、適切なエラー処理を実装してください。
出力先のファイルパスには、PHPスクリプトに書き込み権限があるディレクトリを指定する必要があります。誤って既存の重要なファイルを上書きしないよう、出力パスの管理には十分な注意を払いましょう。DOMDocument::loadXMLの読み込みが失敗する可能性もあるため、その戻り値も適切にチェックすることが重要です。