【PHP8.x】C14Nメソッドの使い方

C14Nメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

C14Nメソッドは、Dom\Attrオブジェクトが表すXML属性ノードを、Canonical XML(C14N)形式の正規化された文字列として取得するメソッドです。Dom\Attrクラスは、HTMLやXML文書内で、例えば<div id="myDiv">という要素のid="myDiv"のような属性を表現します。

このC14Nメソッドは、与えられた属性ノードの内容を、デジタル署名やXML文書の比較などにおいて、常に一貫した表現を保証するために定められた標準的なXML表現規則であるCanonical XMLに従って変換します。これにより、同じ論理的な内容を持つ属性であっても、異なる書式や宣言で表現される可能性のあるXML文書から、バイト列としても完全に同一の表現を得ることが可能になります。

メソッドは二つのオプション引数を取ります。一つ目の$exclusive引数は、排他的Canonical XML形式を使用するかどうかをブール値で指定します。排他的C14Nは、特にWebサービスのメッセージ署名などで利用され、不必要な名前空間の宣言を含まない簡潔な表現を生成します。二つ目の$withComments引数は、コメントノードを正規化された出力に含めるかどうかをブール値で制御します。これらの引数を利用することで、特定の要件に合わせた正規化された属性の文字列を得ることができ、このメソッドは結果として生成された正規化済み文字列を返します。

構文(syntax)

1<?php
2
3$document = new DOMDocument();
4$element = $document->createElement('example');
5$attribute = $document->createAttribute('id');
6$attribute->value = 'item-123';
7$element->appendChild($attribute);
8$document->appendChild($element);
9
10// Dom\Attr クラスの C14N メソッドの呼び出し
11$c14nOutput = $attribute->C14N(true, false);
12
13?>

引数(parameters)

bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null

  • bool $exclusive = false: trueに設定すると、属性の正規化時に名前空間宣言を親要素に移動させます。
  • bool $withComments = false: trueに設定すると、コメントノードも正規化の対象に含めます。
  • ?array $xpath = null: 正規化する要素をXPathクエリで指定します。
  • ?array $nsPrefixes = null: 正規化の際に含める名前空間プレフィックスの配列を指定します。

戻り値(return)

string|false

C14N メソッドは、属性ノードを正規化された文字列形式で返します。正規化に失敗した場合は false を返します。

サンプルコード

PHP Dom\Attr::C14N で属性を正規化する

1<?php
2
3/**
4 * Dom\Attr::C14N メソッドの使用例を示します。
5 * この関数は、XMLドキュメントを作成し、属性ノードを生成し、
6 * その属性ノードに対してC14N(Canonical XML)正規化を適用します。
7 *
8 * C14NはXMLドキュメントの正規化形式であり、異なるXMLの表現がバイトレベルで
9 * 同一になるように整形するのに使われます。
10 * Dom\Attr::C14N は特定の属性ノードの正規化された文字列表現を返します。
11 * このメソッドは PHP 8 以降で利用可能です。
12 */
13function demonstrateDomAttrC14N(): void
14{
15    // 新しい Dom\Document オブジェクトを作成します。
16    // '1.0' はXMLバージョン、'UTF-8' はエンコーディングです。
17    $dom = new Dom\Document('1.0', 'UTF-8');
18    // 出力時にXMLを整形するための設定です。
19    $dom->formatOutput = true;
20
21    // ルート要素(例: <bookstore>)を作成し、ドキュメントに追加します。
22    $root = $dom->createElement('bookstore');
23    $dom->appendChild($root);
24
25    // 子要素(例: <book>)を作成し、ルート要素に追加します。
26    $book = $dom->createElement('book');
27    $root->appendChild($book);
28
29    // book 要素に属性(例: <book id="BK101">)を追加します。
30    $attributeName = 'id';
31    $attributeValue = 'BK101';
32
33    // Dom\Attr オブジェクトを直接作成します。
34    // この時点ではまだ要素には関連付けられていません。
35    $attr = $dom->createAttribute($attributeName);
36    $attr->value = $attributeValue;
37
38    // 作成した属性を book 要素に追加します。
39    $book->setAttributeNode($attr);
40
41    echo "--- 生成されたXMLドキュメント ---\n";
42    // ドキュメント全体をXML文字列として保存し、表示します。
43    echo $dom->saveXML();
44    echo "\n";
45
46    echo "--- Dom\\Attr::C14N() の結果 ---\n";
47
48    // Dom\Attr::C14N() メソッドを呼び出します。
49    // このメソッドは、属性ノードの正規化された文字列表現を返します。
50    // 引数は全てオプションなので、最もシンプルな形で呼び出します。
51    // $exclusive, $withComments, $xpath, $nsPrefixes はデフォルト値が使用されます。
52    $c14nString = $attr->C14N();
53
54    if ($c14nString === false) {
55        // 処理が失敗した場合(通常は発生しにくいですが、エラーチェックは重要です)
56        echo "エラー: Dom\\Attr::C14N() 処理に失敗しました。\n";
57    } else {
58        // 処理が成功した場合、正規化された文字列を表示します。
59        echo "元の属性: '{$attributeName}=\"{$attributeValue}\"'\n";
60        echo "正規化された属性文字列: '{$c14nString}'\n";
61        echo "\n";
62        echo "補足: 'Dom\\Attr::C14N' は、属性ノード自体を正規化された形式で表現します。\n";
63        echo "通常は '属性名=\"属性値\"' の形式が返されます。\n";
64        echo "これは、XML文書全体のC14Nとは異なり、個別の属性のシリアライズに焦点を当てています。\n";
65    }
66}
67
68// 上記の関数を実行して、Dom\Attr::C14N の動作を確認します。
69demonstrateDomAttrC14N();

PHPのDom\Attr::C14Nメソッドは、XMLドキュメント内の特定の属性ノードをC14N(Canonical XML)と呼ばれる標準的な形式に正規化し、その文字列表現を返す機能を提供します。C14Nとは、XMLの異なる表現をバイトレベルで一意な形に整えるための規格です。

このサンプルコードでは、まず新しいXMLドキュメントを作成し、「bookstore」要素の中に「book」要素を配置しています。次に、「book」要素に「id="BK101"」という属性を追加します。Dom\Attr::C14Nメソッドは、このように作成された個別の属性ノードに対して呼び出されます。

メソッドを呼び出す際、$exclusive$withCommentsといった引数を指定できますが、これらはオプションであり、省略するとデフォルト値が適用されます。引数を指定しない場合、最もシンプルな形で属性が正規化されます。戻り値は、正規化された属性の文字列表現、例えば「id="BK101"」のような文字列となります。処理が失敗した場合はfalseが返されます。

Dom\Attr::C14Nは、XMLドキュメント全体のC14Nではなく、あくまで個々の属性ノードに焦点を当てて正規化を行います。これにより、特定の属性が常に同じバイト列として表現されることが保証され、XMLの比較や署名などの処理において一貫性を保つのに役立ちます。このメソッドはPHP 8以降で利用可能です。

Dom\Attr::C14Nメソッドは、XMLドキュメント全体の正規化ではなく、特定の属性ノードのみを対象とします。このメソッドはPHP 8以降で利用可能な点にご注意ください。実行結果は、成功すると正規化された属性文字列(例: id="BK101") を返し、失敗するとfalseを返すため、必ず戻り値の厳密なチェックを行ってください。オプション引数は名前空間やXPath指定など、より高度な正規化を制御する際に使用されますが、単純な属性の正規化では通常デフォルト値で問題ありません。メソッドの適用範囲を誤解しないよう注意が必要です。

PHP Dom\Attr::C14N でXML属性を正規化する

1<?php
2
3/**
4 * Dom\Attr::C14N メソッドの基本的な使用例を示します。
5 * このメソッドは、XML属性ノードをXML正規化 (Canonical XML) 形式に変換します。
6 * PHP 8以降では、C14N 1.1 アルゴリズムが内部的にサポートされており、
7 * XMLコンテンツの一貫性検証やデジタル署名などで利用されます。
8 *
9 * @return void
10 */
11function demonstrateDomAttrC14N(): void
12{
13    // 1. DOMDocument オブジェクトを作成し、XML構造を構築します。
14    $dom = new DOMDocument('1.0', 'UTF-8');
15    // 出力を整形し、人間が読みやすくします。
16    $dom->formatOutput = true;
17
18    // ルート要素を作成し、ドキュメントに追加します。
19    $root = $dom->createElement('root');
20    $dom->appendChild($root);
21
22    // 属性ノードを作成し、特殊文字を含む値を設定します。
23    // C14Nはこれらの特殊文字をXMLエンティティに変換します。
24    $attr = $dom->createAttribute('exampleAttribute');
25    $attr->value = 'value with & < > " \' chars.'; // &、<、>、"、' を含む値
26    $root->appendChild($attr);
27
28    // 2. 作成した属性ノード (DOMAttrオブジェクト) を取得します。
29    // PHP 8では、DOMAttrクラスはDom\Attr名前空間に属しますが、
30    // 互換性のためにグローバル名前空間でもDOMAttrとして利用でき、
31    // Dom\Attrを継承しています。
32    $domAttr = $root->getAttributeNode('exampleAttribute');
33
34    // 属性が正しく取得できたか確認します。
35    if (!$domAttr instanceof Dom\Attr) {
36        echo "エラー: Dom\\Attr オブジェクトを取得できませんでした。\n";
37        return;
38    }
39
40    echo "--- 元のXMLドキュメント ---\n";
41    echo $dom->saveXML();
42    echo "\n";
43    echo "元の属性値: " . $domAttr->nodeValue . "\n\n";
44
45    // 3. Dom\Attr::C14N メソッドを呼び出して属性を正規化します。
46    // PHP 8では、このメソッドはC14N 1.1アルゴリズムを内部的に使用します。
47    // 引数を指定しない場合、デフォルトのinclusive Canonical XMLが適用されます。
48    // 戻り値は正規化された属性の文字列です(例: ' exampleAttribute="value &amp; &lt; &gt; &quot; &apos; chars."')。
49    $canonicalizedString = $domAttr->C14N();
50
51    if ($canonicalizedString === false) {
52        echo "エラー: 属性のC14N正規化に失敗しました。\n";
53    } else {
54        echo "--- C14N正規化された属性文字列 ---\n";
55        echo "(PHP 8ではC14N 1.1アルゴリズムが適用されます)\n";
56        echo $canonicalizedString . "\n";
57        echo "\n";
58        echo "注目点:\n";
59        echo "- ' 属性名=\"属性値\" ' の形式で出力されます。\n";
60        echo "- 属性値内の特殊文字 '&', '<', '>', '\"' はそれぞれ '&amp;', '&lt;', '&gt;', '&quot;' にエスケープされます。\n";
61        echo "- 属性値内の ''' (シングルクォート) は '&apos;' にエスケープされます (C14N 1.1の標準的な挙動)。\n";
62    }
63}
64
65// 関数を実行して、Dom\Attr::C14N の動作を確認します。
66demonstrateDomAttrC14N();
67

このサンプルコードは、PHP 8で導入されたDom\Attr::C14Nメソッドの基本的な使い方を示しています。このメソッドは、XML属性ノードを「Canonical XML (XML正規化)」という標準形式に変換するもので、特にXMLコンテンツの整合性検証やデジタル署名などで利用されます。PHP 8以降では、内部的にC14N 1.1アルゴリズムが適用されます。

コードではまずDOMDocumentを作成し、特殊文字を含む属性値「value with & < > " ' chars.」を持つ属性ノードを設定しています。その後、この属性ノードに対し引数なしでC14N()メソッドを呼び出しています。引数を省略した場合、デフォルトで包括的な正規化が行われます。$exclusive$withCommentsなどの引数で正規化の挙動を詳細に制御できます。

C14N()メソッドは、正規化された属性の文字列を返します。この文字列は「exampleAttribute="value &amp; &lt; &gt; &quot; &apos; chars."」の形式となり、属性値に含まれる特殊文字がそれぞれXMLエンティティ(&amp;&lt;&gt;&quot;&apos;)に変換されます。もし正規化に失敗した場合はfalseが返されます。この正規化は、XMLデータの一貫性を保証するために非常に重要です。

PHP 8以降のDom\Attr::C14N()メソッドは、XML属性をC14N 1.1アルゴリズムで正規化します。このメソッドは、属性名と属性値を含む文字列を返し、値内の特殊文字(& < > " ')は適切なXMLエンティティ(&amp; &lt; &gt; &quot; &apos;)にエスケープされます。特にシングルクォートが&apos;となる点に注意が必要です。メソッドが失敗するとfalseを返すため、必ず戻り値を確認し、エラー処理を行ってください。PHP 8ではDom\Attr名前空間に属しますが、既存のDOMAttrクラスとの互換性も考慮されています。

関連コンテンツ

関連プログラミング言語

【PHP8.x】C14Nメソッドの使い方 | いっしー@Webエンジニア