【PHP8.x】Dom\Entity::C14NFile()メソッドの使い方
C14NFileメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『C14NFileメソッドは、エンティティノードを正規化(C14N)し、その結果をファイルに保存する処理を実行するメソッドです。正規化とは、XML文書を一意の形式に変換する標準的なプロセスのことで、Canonical XMLの略称であるC14Nとして知られています。この処理により、例えば属性の順序や空白の扱いなどが統一され、意味的に同じ内容を持つXML文書は必ず同じバイト列表現となります。これは、XMLデジタル署名の検証など、文書の同一性を厳密に比較する必要がある場面で非常に重要です。このメソッドは、第一引数に出力先のファイルパスを指定します。さらに、後続のオプション引数で、コメントを含めるかどうかや、特定のノードセットのみを対象とする排他的正規化を行うかどうかなどを制御できます。メソッドの実行が成功すると、ファイルに書き込まれたバイト数を返し、失敗した場合はfalseを返します。このメソッドを使用することで、XML文書内の特定のエンティティ部分を標準化された形式でファイルに確実に出力できます。
構文(syntax)
1public function C14NFile( 2 string $uri, 3 bool $exclusive = false, 4 bool $with_comments = false, 5 ?array $xpath = null, 6 bool $ns_prefixes = false 7): int|false;
引数(parameters)
string $uri, bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null
- string $uri: 正規化するDOMドキュメントのURIを指定します。
- bool $exclusive = false: trueに設定すると、排他的な正規化モードが有効になります。
- bool $withComments = false: trueに設定すると、コメントノードも正規化対象に含まれます。
- ?array $xpath = null: 正規化対象のノードをXPath式で指定します。
- ?array $nsPrefixes = null: 名前空間プレフィックスの配列を指定します。
戻り値(return)
int|false
C14NFileメソッドは、XML文書の正規化処理が成功した場合は1を、失敗した場合はfalseを返します。
サンプルコード
PHPによるXML正規化とファイル保存
1<?php 2 3/** 4 * XML文字列を正規化し、指定されたファイルに書き込みます。 5 * 6 * この関数は、PHPの標準DOM拡張にあるDOMDocument::C14NFileメソッドを使用します。 7 * これは、XMLドキュメント全体をC14N (Canonical XML) 標準形式でファイルに保存するのに役立ちます。 8 * 9 * @param string $xmlString 正規化するXMLドキュメントの文字列。 10 * @param string $outputUri 正規化されたXMLを書き込むファイルパスまたはURI。 11 * @param bool $exclusive 排他的な正規化アルゴリズムを使用するかどうか。 12 * @param bool $withComments 正規化された出力にコメントを含めるかどうか。 13 * @param ?array $xpath XPath式にマッチするノードのみを対象とする場合のXPath式の配列。 14 * @param ?array $nsPrefixes XPathで名前空間プレフィックスを使用する場合のプレフィックスとURIのマッピング。 15 * @return int|false 書き込まれたバイト数、または失敗した場合はfalse。 16 */ 17function saveNormalizedXmlToFile( 18 string $xmlString, 19 string $outputUri, 20 bool $exclusive = false, 21 bool $withComments = false, 22 ?array $xpath = null, 23 ?array $nsPrefixes = null 24): int|false { 25 $dom = new DOMDocument(); 26 // XML文字列をDOMオブジェクトにロードします。 27 // ロードに失敗した場合はfalseを返します。 28 if (!$dom->loadXML($xmlString)) { 29 // エラーログに出力 (本番環境ではより詳細なエラーハンドリングを推奨) 30 error_log("XML文字列のロードに失敗しました。"); 31 return false; 32 } 33 34 // DOMDocument::C14NFile メソッドを使用してXMLを正規化し、ファイルに書き込みます。 35 // 戻り値は書き込まれたバイト数、または失敗した場合はfalseです。 36 return $dom->C14NFile($outputUri, $exclusive, $withComments, $xpath, $nsPrefixes); 37} 38 39// --- 使用例 --- 40 41// 正規化するサンプルXMLデータ 42$sampleXml = <<<XML 43<?xml version="1.0" encoding="UTF-8"?> 44<root xmlns:app="http://example.com/app"> 45 <!-- これはサンプルコメントです --> 46 <data id="1">Hello World</data> 47 <app:settings> 48 <option enabled="true"/> 49 </app:settings> 50</root> 51XML; 52 53// 正規化されたXMLを保存するための一時ファイルパスを生成 54$tempFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'c14n_output_' . uniqid() . '.xml'; 55 56echo "XML正規化処理を開始します。\n"; 57 58// コメントを含め、排他的ではない正規化を実行 59$bytesWritten = saveNormalizedXmlToFile($sampleXml, $tempFilePath, false, true); 60 61if ($bytesWritten !== false) { 62 echo "成功: '{$tempFilePath}' に {$bytesWritten} バイトが書き込まれました。\n"; 63 echo "正規化されたXMLの内容:\n"; 64 // 作成されたファイルの内容を表示 65 echo file_get_contents($tempFilePath) . "\n\n"; 66} else { 67 echo "エラー: XMLの正規化またはファイルへの書き込みに失敗しました。\n"; 68} 69 70// 後処理: 作成された一時ファイルを削除します。 71if (file_exists($tempFilePath)) { 72 unlink($tempFilePath); 73 echo "一時ファイル '{$tempFilePath}' を削除しました。\n"; 74}
PHPのDOMDocument::C14NFileメソッドは、XMLドキュメントの内容を特定のルールに基づいて標準的な形式(Canonical XML、略してC14N)に変換し、その結果を指定したファイルに保存する機能を提供します。これは、異なる表現を持つXMLドキュメントの内容を統一し、比較やデジタル署名といった用途で一貫性を保つために利用されます。
このメソッドの最初の引数$uriは、正規化されたXMLが書き込まれるファイルパスを指定します。$exclusive引数をtrueに設定すると、排他的な正規化アルゴリズムが適用されます。また、$withComments引数をtrueにすると、正規化された出力にコメントが含まれるようになります。オプションとして、$xpathと$nsPrefixes引数を用いることで、XMLドキュメント全体ではなく、XPath式で指定された特定のノードのみを対象に正規化を実行することも可能です。
メソッドの戻り値は、処理が成功した場合はファイルに書き込まれたバイト数を示す整数値ですが、何らかの理由で処理が失敗した場合はfalseが返されます。サンプルコードでは、与えられたXML文字列をDOMDocumentオブジェクトに読み込み、C14NFileメソッドを使用して正規化されたXMLを一時ファイルに保存し、その内容を表示する一連の流れが示されています。これにより、XMLの正規化処理がどのように行われるかを確認できます。
このサンプルコードは、XMLをC14N (Canonical XML) 形式で正規化し、ファイルへ書き込む方法を示しています。DOMDocument::loadXMLやC14NFileメソッドは、処理に失敗した場合にfalseを返しますので、必ずその戻り値をチェックし、適切にエラー処理を行うことが重要です。特にファイル書き込みは、指定されたパスのパーミッションや存在確認が必要です。$uri引数には書き込み権限のある有効なファイルパスを指定してください。$exclusiveや$withCommentsなどのオプション引数は、正規化されたXMLの形式に影響を与えるため、用途に応じて正しく理解し設定することが求められます。一時ファイルなどを利用する際は、処理完了後に適切に削除するなどのリソース管理を心がけてください。リファレンス情報のDom\EntityはPHP 8で導入された新しいDOM拡張の一部ですが、既存のDOMDocumentクラスを通してメソッドを利用できます。
PHP XML正規化とファイル出力
1<?php 2 3/** 4 * XMLファイルを正規化し、その結果を新しいファイルに書き出す関数。 5 * キーワード「php cp」から、XMLコンテンツの処理とファイルへの保存を意図しています。 6 * 7 * @param string $inputXmlPath 入力XMLファイルのパス 8 * @param string $outputXmlPath 出力XMLファイルのパス 9 * @return bool 処理が成功した場合は true、失敗した場合は false 10 */ 11function canonicalizeXmlToFile(string $inputXmlPath, string $outputXmlPath): bool 12{ 13 // 1. サンプル入力XMLファイルを一時的に作成します。 14 // このファイルは、正規化処理の入力として使用されます。 15 $initialXmlContent = <<<XML 16<?xml version="1.0" encoding="UTF-8"?> 17<root> 18 <element attr="value"> 19 <!-- これはテストコメントです --> 20 <child>Hello World</child> 21 </element> 22</root> 23XML; 24 file_put_contents($inputXmlPath, $initialXmlContent); 25 26 // 2. Dom\Document クラスのインスタンスを作成し、XMLファイルをロードします。 27 // Dom\Document はXMLドキュメント全体を扱うための主要なクラスです。 28 $dom = new Dom\Document(); 29 if (!$dom->load($inputXmlPath)) { 30 echo "エラー: 入力XMLファイル '{$inputXmlPath}' をロードできませんでした。\n"; 31 unlink($inputXmlPath); // 一時ファイルを削除 32 return false; 33 } 34 35 // 3. C14NFile メソッドを使用して、XMLを正規化し、結果を出力ファイルに書き込みます。 36 // このメソッドは、XMLのバイト表現を標準形式(Canonical XML)に変換し、指定されたURIに保存します。 37 // PHP 8では名前付き引数を使用できます。 38 // 39 // 引数: 40 // - $outputXmlPath: 正規化されたXMLを書き出すファイルのURI(パス)。 41 // - exclusive: 排他的正規化モードを使用するかどうか。falseで通常モード(デフォルト)。 42 // - withComments: 正規化された出力にコメントを含めるかどうか。trueで含める(デフォルトはfalse)。 43 $bytesWritten = $dom->C14NFile( 44 $outputXmlPath, 45 exclusive: false, 46 withComments: true 47 ); 48 49 if ($bytesWritten === false) { 50 echo "エラー: XMLの正規化とファイルへの書き込みに失敗しました '{$outputXmlPath}'。\n"; 51 unlink($inputXmlPath); // 一時ファイルを削除 52 return false; 53 } 54 55 echo "XMLを正常に正規化し、'{$outputXmlPath}' に書き込みました。書き込まれたバイト数: {$bytesWritten}バイト。\n"; 56 57 // 4. 出力ファイルの内容を確認(任意)。 58 // 成功した場合、正規化されたXMLファイルの内容を表示します。 59 if (file_exists($outputXmlPath)) { 60 echo "\n--- '{$outputXmlPath}' の内容 ---\n"; 61 echo file_get_contents($outputXmlPath); 62 echo "\n-------------------------------------\n"; 63 } 64 65 // 5. 使用した一時ファイルをクリーンアップします。 66 unlink($inputXmlPath); 67 if (file_exists($outputXmlPath)) { // 書き込み失敗時にファイルが存在しない可能性を考慮 68 unlink($outputXmlPath); 69 } 70 71 return true; 72} 73 74// スクリプトのエントリーポイント: サンプル関数の実行 75$inputFilePath = __DIR__ . '/temp_input.xml'; 76$outputFilePath = __DIR__ . '/temp_output_canonical.xml'; 77 78if (canonicalizeXmlToFile($inputFilePath, $outputFilePath)) { 79 echo "サンプルコードの実行が成功しました。\n"; 80} else { 81 echo "サンプルコードの実行が失敗しました。\n"; 82} 83
PHP 8で提供されるDom\Document::C14NFileメソッドは、XMLドキュメントを「Canonical XML(正規化されたXML)」形式に変換し、その結果を指定されたファイルに保存する機能を提供します。このメソッドは、XMLの内容はそのままに、表現上の差異(空白文字や属性の順序など)を統一したい場合に非常に有効です。キーワード「php cp」のように、既存のXMLファイルを標準化して別ファイルとして保存したい際に利用できます。
このメソッドは、XMLドキュメント全体を扱うDom\Documentクラスのインスタンスから呼び出されます。
引数について、$uriには正規化されたXMLの出力先ファイルパスを指定します。$exclusiveは排他的正規化モードを使用するかどうかを真偽値で設定し、通常はfalse(標準モード)で問題ありません。$withCommentsは、正規化された出力にXMLコメントを含めるかどうかを真偽値で指定します。trueに設定するとコメントが保持されます。
戻り値は、処理が成功した場合はファイルに書き込まれたバイト数(int)を返し、書き込みに失敗した場合はfalseを返します。この戻り値を確認することで、ファイルの書き込みが正常に行われたか判断できます。XMLの厳密な比較や電子署名などに際し、特定の形式でXMLファイルを生成する場面で役立ちます。
PHPのDom\Entity::C14NFileメソッドは、XMLファイルを正規化して指定のファイルへ出力します。リファレンスではDom\Entityクラスに所属とありますが、通常はDom\Documentインスタンスからこのメソッドを呼び出しますのでご注意ください。
ファイルパスは適切に指定し、書き込み権限があるか確認してください。Dom\Document::load()やC14NFile()メソッドがfalseを返す場合、処理が失敗しています。必ず戻り値を確認し、エラー処理を記述することが重要です。
サンプルコードのように一時ファイルを生成する場合、処理の成功・失敗にかかわらずunlinkで確実に削除するよう心がけてください。C14NFileは単なるファイルコピーではなく、XMLの標準形式への変換(正規化)を行うため、元のファイルと内容が異なる場合があります。引数のwithCommentsはコメントを含めるかを制御しますので、必要に応じて設定してください。PHP 8の名前付き引数を利用している点も補足します。