【PHP8.x】DOMCdataSection::C14NFile()メソッドの使い方
C14NFileメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
C14NFileメソッドは、DOMCdataSectionクラスに属し、現在のCDATAセクションを含むDOMツリーの一部を、XMLの正規化(Canonical XML、C14N)ルールに従って指定されたファイルに保存するメソッドです。XMLの正規化とは、XML文書のさまざまな表記上の違い(例えば、空白文字の扱い方、属性の順序、名前空間の宣言方法など)を吸収し、その内容が論理的に同一であることを保証するための標準的な処理を指します。これにより、異なる環境で作成されたXML文書であっても、その本質的な内容が変わっていないかを正確に比較したり、デジタル署名の検証を行ったりすることが可能になります。
このメソッドは、引数として出力先のファイルパスを受け取り、さらに正規化のオプション(排他的正規化を行うか否かなど)や、コメントノードを含めるかどうかのフラグを指定することができます。指定されたDOMノード以下の構造を、これらのオプションに基づいて正規化されたXML形式でファイルに書き出します。
しかしながら、このC14NFileメソッドはPHP 8.0.0で非推奨となり、PHP 9.0.0で削除されました。そのため、最新のPHP環境での利用は推奨されません。現在、同様の機能を実現するには、まずDOMNodeクラスが提供するC14N()メソッドを使用して正規化されたXMLを文字列として取得し、その結果の文字列をfile_put_contents()のようなファイル書き込み関数を用いてファイルに保存する方法が推奨されています。この代替手法を用いることで、システムの互換性を保ちつつ、XMLの正規化された形式をファイルに出力することが可能です。
構文(syntax)
1$domCdataSectionInstance->C14NFile(string $uri, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null);
引数(parameters)
string $uri, bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null
- string $uri: C14N化するXML文書のURIを指定する文字列
- bool $exclusive = false: 排他的C14Nを行うかどうかを指定する真偽値。デフォルトはfalse
- bool $withComments = false: コメントを含めてC14Nを行うかどうかを指定する真偽値。デフォルトはfalse
- ?array $xpath = null: C14N化の対象をXPath式で絞り込むための配列。nullの場合は文書全体を対象とする
- ?array $nsPrefixes = null: 名前空間プレフィックスを明示的に指定するための連想配列。nullの場合は自動的に決定される
戻り値(return)
int|false
このメソッドは、C14N (Canonical XML) 形式でセクションの内容をファイルに書き込んだ場合、その書き込みバイト数を整数で返します。書き込みに失敗した場合は false を返します。
サンプルコード
PHP DOM C14NFile でXMLを正規化・保存する
1<?php 2 3/** 4 * XML文書を正規化(Canonicalization)し、ファイルに保存するPHPスクリプトです。 5 * 6 * C14Nは、XML文書を特定の方法で正規化し、文書の同一性を比較可能にするための標準です。 7 * 主にXMLデジタル署名などで、XML文書の内容が変更されていないことを確認する目的で使用されます。 8 * 9 * このスクリプトは、DOMDocumentクラスのC14NFileメソッドを使用します。 10 * 11 * @param string $xmlString 正規化するXMLコンテンツの文字列。 12 * @param string $outputFilePath 正規化されたXMLを保存するファイルのパス。 13 * @param bool $exclusive 排他的C14Nを使用するかどうか。デフォルトはfalse(非排他的)。 14 * @param bool $withComments XMLコメントを正規化された出力に含めるかどうか。デフォルトはfalse。 15 * @return bool 処理が成功した場合はtrue、失敗した場合はfalse。 16 */ 17function canonicalizeXmlToFile( 18 string $xmlString, 19 string $outputFilePath, 20 bool $exclusive = false, 21 bool $withComments = false 22): bool { 23 // DOMDocument オブジェクトを作成 24 $dom = new DOMDocument('1.0', 'UTF-8'); 25 26 // libxmlのエラーハンドリングを内部に設定し、警告などを捕捉できるようにする 27 // これにより、XMLの読み込みエラーが発生してもスクリプトが即座に停止しない 28 libxml_use_internal_errors(true); 29 30 // XML文字列をDOMに読み込む 31 if (!$dom->loadXML($xmlString)) { 32 echo "エラー: XMLの読み込みに失敗しました。\n"; 33 foreach (libxml_get_errors() as $error) { 34 echo " LIBXMLエラー: " . $error->message; 35 } 36 libxml_clear_errors(); // 処理後、エラー情報をクリア 37 return false; 38 } 39 libxml_clear_errors(); // 処理後、エラー情報をクリア 40 41 // XMLを正規化し、指定されたファイルに保存します。 42 // C14NFile メソッドはDOMDocumentクラスに属します。 43 // 引数: $uri, $exclusive, $withComments, $xpath (null), $nsPrefixes (null) 44 // $xpath と $nsPrefixes はここでは省略し、デフォルトのnullが使用されます。 45 $bytesWritten = $dom->C14NFile($outputFilePath, $exclusive, $withComments); 46 47 if ($bytesWritten === false) { 48 echo "エラー: XMLのC14N正規化ファイル保存に失敗しました。\n"; 49 return false; 50 } 51 52 echo "XMLが正規化され、'{$outputFilePath}' に保存されました。\n"; 53 echo "書き込まれたバイト数: {$bytesWritten}\n"; 54 return true; 55} 56 57// -------------------------------------------------------------------------- 58// サンプル使用例 59// -------------------------------------------------------------------------- 60 61// 正規化するXMLデータ 62$sampleXml = <<<XML 63<?xml version="1.0" encoding="UTF-8"?> 64<root xmlns:ex="http://example.com/ns"> 65 <!-- これはXMLコメントです --> 66 <element attribute="value"> 67 <child> こんにちは世界 </child> 68 </element> 69 <ex:otherElement/> 70</root> 71XML; 72 73// 出力ファイルパス 74$outputFile = 'canonicalized_output.xml'; 75 76// 関数を呼び出してXMLを正規化し、ファイルに保存 77// この例では、コメントを含めて正規化します (withComments = true)。 78// 排他的C14Nは使用しません (exclusive = false)。 79if (canonicalizeXmlToFile($sampleXml, $outputFile, false, true)) { 80 echo "\n生成されたファイルの内容 ('{$outputFile}'):\n"; 81 // 生成されたファイルの内容を表示して確認します。 82 // HTMLspecialcharsは、出力がターミナルではなくHTMLコンテキストで表示される場合に 83 // タグが誤って解釈されないようにするためのものです。 84 echo htmlspecialchars(file_get_contents($outputFile)) . "\n"; 85} else { 86 echo "\nXML正規化処理に失敗しました。\n"; 87} 88 89// 必要に応じて、生成されたファイルを削除できます。 90// @unlink($outputFile); 91 92?>
PHPのDOMDocumentクラスが提供するC14NFileメソッドは、XML文書を標準的な方法で正規化(Canonicalization: C14N)し、その結果を指定されたファイルに保存するための機能です。C14Nは、XML文書の見た目や構造がわずかに異なっていても、内容が同じであれば同じ表現になるように変換する国際標準であり、主にXMLデジタル署名などでの内容の同一性検証に利用されます。
このメソッドは、string $uriで指定されたファイルパスに正規化されたXMLを出力します。また、bool $exclusive引数で排他的C14N(デフォルトは非排他的)、bool $withComments引数でXMLコメントを正規化結果に含めるかどうか(デフォルトは含めない)を制御できます。オプションとして、?array $xpathで正規化する要素をXPath式で指定したり、?array $nsPrefixesで対象の名前空間プレフィックスを限定することも可能です。
処理が成功した場合、メソッドはファイルに書き込まれたバイト数をint型で返します。何らかの理由で処理が失敗した場合はfalseを返しますので、戻り値を確認してエラーハンドリングを行うことが重要です。この機能を利用することで、XML文書の信頼性や整合性をプログラム的に保証できるようになります。
C14NFileメソッドはXMLの正規化(C14N)を行い、その結果をファイルに保存します。このメソッドはリファレンス情報にあるDOMCdataSectionではなく、実際にはDOMDocumentクラスに属しますのでご注意ください。主にXMLデジタル署名など、文書の同一性を検証する特殊な用途で利用されます。
XMLの読み込みやC14N処理が失敗する可能性があるため、関数からの戻り値がfalseでないか常に確認し、libxml_use_internal_errorsで詳細なエラーを捕捉する堅牢なエラーハンドリングが重要です。ファイルへの書き込みには、指定したパスへの書き込み権限が必要です。引数の$exclusiveや$withCommentsは正規化の挙動に影響を与え、$xpathや$nsPrefixesは特定のXML要素のみを正規化する高度な機能ですが、基本的には省略可能です。
PHP DOMCdataSection::C14NFile によるXML正規化
1<?php 2 3/** 4 * XMLドキュメントを生成し、Canonical XML (C14N) 形式でファイルに保存します。 5 * 6 * この関数は、指定されたXML構造を正規化し、その結果を新しいファイルとして出力します。 7 * キーワード「cp」が示すように、XMLデータを別のファイルに「コピー」(この場合は正規化して保存)する 8 * 操作に相当します。 9 * 10 * @param string $outputFilePath 正規化されたXMLを保存するファイルのパス。 11 * @param bool $withComments 正規化結果にXMLコメントを含めるか。 12 * @return bool 処理が成功した場合は true、失敗した場合は false。 13 */ 14function canonicalizeXmlToFile(string $outputFilePath, bool $withComments = false): bool 15{ 16 // DOMDocument を作成し、基本的な設定を行います。 17 $dom = new DOMDocument('1.0', 'UTF-8'); 18 $dom->preserveWhiteSpace = false; // DOMツリー構築時の空白文字の扱いを設定 (整形のため) 19 $dom->formatOutput = true; // 出力を見やすく整形 (C14Nの動作とは直接関係ありません) 20 21 // XML構造の構築 22 $root = $dom->createElement('root'); 23 // 名前空間を追加 (正規化の例として) 24 $root->setAttribute('xmlns', 'http://example.com/ns/test'); 25 $dom->appendChild($root); 26 27 $itemElement = $dom->createElement('item', 'データ & テキスト'); 28 $itemElement->setAttribute('id', '1'); 29 $root->appendChild($itemElement); 30 31 // DOMCdataSection インスタンスの作成と追加 32 // C14NではCDATAセクションの内容は通常、エスケープされたテキストとして扱われますが、 33 // ここではサンプルとしてCDATAセクションを含めます。 34 $cdataSection = $dom->createCDATASection('特別な <タグ> と "引用符" のあるテキスト'); 35 $root->appendChild($cdataSection); 36 37 // コメントの追加($withComments が true の場合にのみ正規化結果に含まれる) 38 $commentNode = $dom->createComment('これは正規化テスト用のコメントです。'); 39 $root->appendChild($commentNode); 40 41 // DOMNode::C14NFile メソッドを呼び出します。 42 // DOMCdataSection は DOMNode を継承しており、DOMDocument も DOMNode を継承しています。 43 // このメソッドは DOMNode インスタンスから呼び出すことができ、 44 // 現在のノード(DOMDocumentの場合、ドキュメント全体)を正規化してファイルに書き出します。 45 $bytesWritten = $dom->C14NFile( 46 $outputFilePath, 47 false, // $exclusive: 排他的正規化モード (通常は false) 48 $withComments // $withComments: XMLコメントを含めるか否か 49 // その他の引数 ($xpath, $nsPrefixes) は、より詳細な制御が必要な場合に利用します。 50 ); 51 52 if ($bytesWritten === false) { 53 // エラー処理 54 error_log('XMLの正規化とファイルへの書き込みに失敗しました: ' . $outputFilePath); 55 return false; 56 } 57 58 echo "XMLが正常に正規化され、ファイルに保存されました: " . $outputFilePath . " (" . $bytesWritten . " バイト)\n"; 59 return true; 60} 61 62// --- 関数利用の例 --- 63$outputFileBase = 'canonicalized_xml'; 64 65// 1. コメントを含めないで正規化 66$outputFileNoComments = $outputFileBase . '_no_comments.xml'; 67echo "--- コメントを含めないで正規化を実行 ---\n"; 68if (canonicalizeXmlToFile($outputFileNoComments, false)) { 69 echo "ファイル内容:\n"; 70 echo file_get_contents($outputFileNoComments) . "\n\n"; 71} 72 73// 2. コメントを含めて正規化 74$outputFileWithComments = $outputFileBase . '_with_comments.xml'; 75echo "--- コメントを含めて正規化を実行 ---\n"; 76if (canonicalizeXmlToFile($outputFileWithComments, true)) { 77 echo "ファイル内容:\n"; 78 echo file_get_contents($outputFileWithComments) . "\n"; 79} 80 81// 注意: このサンプルコードは実行環境にファイルを作成します。 82// 実行後にこれらのファイルが不要な場合は、手動で削除してください。 83// 例: unlink($outputFileNoComments); 84// unlink($outputFileWithComments);
PHPのDOMNode::C14NFileメソッドは、XMLドキュメントを指定されたCanonical XML (C14N) 形式でファイルに保存するために使用されます。キーワード「cp」が示すように、XMLデータを正規化された標準形式に「コピー」して新しいファイルに出力する操作に相当します。
このサンプルコードでは、DOMDocumentクラスを使用して簡単なXML構造(ルート要素、アイテム要素、CDATAセクション、コメントなど)を構築しています。その後、構築したXMLドキュメント全体をC14NFileメソッドにより正規化し、指定したファイルに書き出しています。
C14NFileメソッドの第一引数$uriには、正規化されたXMLを保存するファイルのパスを指定します。第三引数$withCommentsをtrueに設定すると、XMLドキュメント内のコメントも正規化結果に含めることができます。このメソッドの戻り値は、ファイルに書き込まれたバイト数を示す整数値、または処理が失敗した場合にはfalseです。これにより、XMLデータの一貫性を保ちながら、標準化された形式でファイルとして保存することが可能です。
このサンプルコードは、PHPのDOMDocumentを利用してXMLデータを正規化し、指定したファイルに保存する処理を示しています。C14NFileメソッドはDOMNodeクラスの機能であり、DOMDocumentからも呼び出してドキュメント全体を正規化・出力できます。第一引数で指定するファイルパスは、書き込み権限のある場所に設定し、既存ファイルは上書きされる点にご留意ください。メソッドの戻り値は、成功時に書き込まれたバイト数、失敗時にfalseとなりますので、必ずその戻り値をチェックしてエラーハンドリングを行うことが重要です。アプリケーション運用では、生成されたファイルが不要になった場合の削除管理も考慮してください。より高度な正規化には、追加の引数を活用できます。