【PHP8.x】Dom\Document::isSameNode()メソッドの使い方
isSameNodeメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『isSameNodeメソッドは、あるノードが別のノードと同一のオブジェクトであるかどうかを判定するメソッドです』
このメソッドは、引数に指定されたノードが、メソッドを呼び出したノードとメモリ上で全く同じインスタンスを参照している場合に true を返します。それ以外の場合、つまり異なるインスタンスである場合は false を返します。この動作は、PHPの厳密な比較演算子 === を用いて2つのオブジェクト変数を比較するのと同じ結果となります。DOM操作において重要な点として、isEqualNodeメソッドとの違いが挙げられます。isEqualNodeがノードの種類、名前、属性、子ノードといった内容が構造的に等しいかどうかを再帰的に比較するのに対し、isSameNodeは参照が同じであるか、つまり完全に同一のオブジェクトであるかという点のみを判定します。そのため、あるノードを複製(clone)して作成した新しいノードは、内容は同じでもisSameNodeでは false と判定されます。このメソッドにより、2つの変数が同じDOM要素を指しているかを正確に確認できます。
構文(syntax)
1<?php 2// Dom\Document のインスタンス 3$document = new Dom\Document(); 4 5// 比較対象となる Dom\Node のインスタンス 6$other_node = new Dom\Document(); 7 8// 2つのノードが同一であるか (同じオブジェクトを指しているか) を判定します。 9// 戻り値: bool (true または false) 10$result = $document->isSameNode($other_node); 11?>
引数(parameters)
?Dom\Node $otherNode
- ?Dom\Node $otherNode: 比較対象のDOMノード
戻り値(return)
bool
このメソッドは、呼び出し元のDOMNodeオブジェクトが、引数で渡された別のDOMNodeオブジェクトと同一のノードである場合にtrueを、そうでない場合にfalseを返します。
サンプルコード
PHP Dom\Document::isSameNodeでノード比較
1<?php 2 3/** 4 * Dom\Document::isSameNode メソッドの使用例を示します。 5 * 'php isnotempty' のキーワードに対応するため、DOMノードが null でないことを確認してから比較を行います。 6 */ 7function demonstrateIsSameNode(): void 8{ 9 // 1. 新しい Dom\Document オブジェクトを作成します。 10 // これはHTMLドキュメント全体を表すための基盤となります。 11 $document = new Dom\Document(); 12 13 // 2. HTMLコンテンツをロードし、DOMツリーを構築します。 14 // このHTMLからノードを取得し、それらを比較します。 15 $htmlContent = <<<HTML 16 <html> 17 <body> 18 <div id="container"> 19 <p id="first-paragraph">これは最初の段落です。</p> 20 <span id="second-span">これは2番目のスパンです。</span> 21 </div> 22 <p id="another-paragraph">別の段落です。</p> 23 </body> 24 </html> 25 HTML; 26 $document->loadHTML($htmlContent); 27 28 // 3. いくつかのDOMノードを取得します。 29 // getElementById() は、指定されたIDを持つ要素を返します。 30 // 要素が見つからない場合は null を返します。 31 $nodeA = $document->getElementById('first-paragraph'); 32 $nodeB = $document->getElementById('first-paragraph'); // 同じIDのノードを再度取得 33 $nodeC = $document->getElementById('second-span'); 34 $nodeD = $document->getElementById('non-existent-id'); // 存在しないIDを指定 (null が返される) 35 36 echo "--- Dom\Document::isSameNode メソッドの使用例 ---\n"; 37 38 // 4. ノードが存在することを確認し、isSameNode メソッドを使用して比較します。 39 // 'php isnotempty' のキーワードに対応するため、!empty() を使用してノードが null でないことを確認します。 40 // !empty($variable) は、$variable が null, 0, "", [], false などでない場合に true を返します。 41 // Dom\Node オブジェクトは通常、!empty() で true と評価されます。 42 43 // nodeA と nodeB の比較: 同じDOM要素を指すノード同士 44 if (!empty($nodeA) && !empty($nodeB)) { 45 echo "nodeA と nodeB (同じID 'first-paragraph') は "; 46 // isSameNode は、2つのノードがDOMツリー内の同じノードを指している場合に true を返します。 47 echo $nodeA->isSameNode($nodeB) ? "同じノードです。\n" : "異なるノードです。\n"; 48 } else { 49 echo "nodeA または nodeB が見つかりませんでした。\n"; 50 } 51 52 // nodeA と nodeC の比較: 異なるDOM要素を指すノード同士 53 if (!empty($nodeA) && !empty($nodeC)) { 54 echo "nodeA と nodeC (異なるID) は "; 55 echo $nodeA->isSameNode($nodeC) ? "同じノードです。\n" : "異なるノードです。\n"; 56 } else { 57 echo "nodeA または nodeC が見つかりませんでした。\n"; 58 } 59 60 // nodeA と nodeD (存在しないノード、つまり null) の比較 61 // Dom\Node::isSameNode の引数 `$otherNode` は `?Dom\Node` 型なので、null を直接渡すことができます。 62 // null との比較は常に false を返します。 63 if (!empty($nodeA)) { // nodeA が有効なノードである場合のみ実行 64 echo "nodeA と nodeD (存在しないノード) は "; 65 echo $nodeA->isSameNode($nodeD) ? "同じノードです。\n" : "異なるノードです。\n"; 66 } else { 67 echo "nodeA が見つかりませんでした。\n"; 68 } 69 70 // 補足: null 値から isSameNode メソッドを直接呼び出すことはできません。 71 // $nodeD は null なので、もし $nodeD->isSameNode($nodeA) のように呼び出すと TypeError が発生します。 72 if (empty($nodeD)) { 73 echo "\n注意: nodeD は存在しないノードのため null です。null からは Dom\Node::isSameNode を直接呼び出せません。\n"; 74 } 75} 76 77// 作成した関数を実行し、結果を出力します。 78demonstrateIsSameNode();
Dom\Document::isSameNode は、PHPでHTMLなどのDOM(Document Object Model)を操作する際に、二つのDOMノードがDOMツリー内の全く同じオブジェクトであるかを判定するメソッドです。このメソッドは、あるノードが引数として渡された $otherNode と同じ実体であるかを調べます。
引数 $otherNode には比較したい Dom\Node オブジェクトを渡しますが、型が ?Dom\Node であるため、ノードが存在しない場合は null を渡すことも可能です。戻り値は bool 型で、もし二つのノードが同じDOM要素を指していれば true を、そうでなければ false を返します。
サンプルコードでは、Dom\Document を使ってHTMLを読み込み、getElementById() メソッドで特定のIDを持つHTML要素をDOMノードとして取得しています。この getElementById() は、指定されたIDの要素が見つからない場合に null を返す特性があります。そのため、「php isnotempty」のキーワードに対応する形で、!empty($node) を使用してノードが null でないことを確認してから isSameNode を呼び出しています。これは、null 値から直接メソッドを呼び出すとエラーになるのを防ぐための重要なチェックです。
実行結果として、同じIDで取得したノード同士は true を返しますが、異なるIDのノード同士や、有効なノードと null を比較した場合は false を返します。このメソッドは、DOMツリー内でノードの同一性を正確に判断したい場合に非常に有用です。
このサンプルコードでは、DOMノードを取得する際、ノードが見つからない場合にはnullが返されることに注意が必要です。Dom\Node::isSameNodeメソッドは、DOMツリー内の物理的に「同じノード」であるかどうかを比較します。ノードの内容が同じでも、DOMツリー上で異なるインスタンスであればfalseを返します。このメソッドの引数にはnullを渡すことが可能で、その場合、比較結果は常にfalseとなります。しかし、null値の変数から直接isSameNodeメソッドを呼び出そうとすると、TypeErrorが発生しプログラムが停止します。そのため、メソッドを呼び出す前に!empty()などを用いて、対象のノードがnullでないことを必ず確認するようにしてください。これにより、安全かつ正確にコードを利用できます。
PHP Dom\Node::isSameNodeでノード同一性を判定する
1<?php 2 3/** 4 * Dom\Node::isSameNode メソッドの簡単な使用例を示します。 5 * このメソッドは、2つのノードがメモリ上で同じオブジェクト(同じインスタンス)であるかを判定します。 6 * 7 * 注: 提供されたリファレンスでは「所属クラス: Dom\Document」とありますが、 8 * PHP 8のDOM拡張における isSameNode メソッドは Dom\Node クラスに属します。 9 * 以下のサンプルコードは、正しい Dom\Node::isSameNode の使用法を示します。 10 */ 11function demonstrateIsSameNode(): void 12{ 13 // 新しいDOMドキュメントを作成します。 14 $document = new Dom\Document(); 15 16 // HTML構造を構築します。 17 $htmlElement = $document->createElement('html'); 18 $document->appendChild($htmlElement); 19 20 $bodyElement = $document->createElement('body'); 21 $htmlElement->appendChild($bodyElement); 22 23 // 最初のp要素を作成し、body要素に追加します。 24 $paragraph1 = $document->createElement('p', '最初の段落。'); 25 $bodyElement->appendChild($paragraph1); 26 27 // 2番目のp要素を作成し、body要素に追加します。 28 // これは $paragraph1 とは別のノードです。 29 $paragraph2 = $document->createElement('p', '2番目の段落。'); 30 $bodyElement->appendChild($paragraph2); 31 32 // ドキュメントから最初のp要素を再度取得します。 33 // これは、$paragraph1 と同じノードを参照しています。 34 $firstParagraphFromDoc = $document->getElementsByTagName('p')->item(0); 35 36 echo "--- Dom\\Node::isSameNode のデモンストレーション ---" . PHP_EOL; 37 38 // ケース1: 同じ変数に格納されたノード同士を比較します。 39 // 結果: true ($paragraph1 は $paragraph1 自身と同じオブジェクトです) 40 echo '比較対象: $paragraph1 と $paragraph1' . PHP_EOL; 41 echo '結果: '; 42 var_dump($paragraph1->isSameNode($paragraph1)); 43 44 // ケース2: 異なる変数ですが、同じDOMノードを指すオブジェクト同士を比較します。 45 // 結果: true ($paragraph1 と $firstParagraphFromDoc はメモリ上で同じノードを指します) 46 echo '比較対象: $paragraph1 と $firstParagraphFromDoc (DOMから取得)' . PHP_EOL; 47 echo '結果: '; 48 var_dump($paragraph1->isSameNode($firstParagraphFromDoc)); 49 50 // ケース3: 異なるDOMノード同士を比較します。 51 // 結果: false ($paragraph1 と $paragraph2 は異なるオブジェクトです) 52 echo '比較対象: $paragraph1 と $paragraph2 (異なる段落)' . PHP_EOL; 53 echo '結果: '; 54 var_dump($paragraph1->isSameNode($paragraph2)); 55 56 // ケース4: 異なるノードタイプ同士を比較します。 57 // 結果: false ($paragraph1 と $bodyElement は異なるオブジェクトです) 58 echo '比較対象: $paragraph1 と $bodyElement (段落とボディ)' . PHP_EOL; 59 echo '結果: '; 60 var_dump($paragraph1->isSameNode($bodyElement)); 61 62 // ケース5: null との比較 (引数は ?Dom\Node を許容します) 63 // 結果: false (nullはどのDom\Nodeオブジェクトとも同じではありません) 64 echo '比較対象: $paragraph1 と null' . PHP_EOL; 65 echo '結果: '; 66 var_dump($paragraph1->isSameNode(null)); 67} 68 69// 上記のデモンストレーション関数を実行します。 70demonstrateIsSameNode();
PHP 8で導入されたDOM拡張のDom\Node::isSameNodeメソッドは、二つのDOMノードがメモリ上で全く同じオブジェクト(同じインスタンス)であるかを判定するために使用されます。このメソッドは、たとえ同じ内容を持つノードであっても、それぞれが異なるインスタンスとして生成されていればfalseを返し、内容に関わらずメモリ上の参照が同じであればtrueを返します。
引数$otherNodeには比較したい別のDom\Nodeオブジェクト、またはnullを指定できます。nullを渡した場合は、どのノードとも同じではないため常にfalseが返されます。戻り値は比較結果を示すbool(真偽値)です。
サンプルコードでは、Dom\Document内に複数のHTML要素(ノード)を作成し、このメソッドの挙動を検証しています。例えば、同じ変数に格納されたノード同士や、一度DOMに追加されてから再度取得したノード(これらはメモリ上で同じ実体です)を比較するとtrueになります。一方で、異なる目的で作成された二つの要素や、異なるタイプの要素(例えば段落とボディ要素)を比較するとfalseが返されます。これらはそれぞれ独立したオブジェクトとして扱われるためです。このようにisSameNodeメソッドは、DOM操作において、特定のノードが本当に同じ実体であるかを厳密に確認したい場合に役立ちます。
このサンプルコードは、Dom\Node::isSameNodeメソッドの正しい使い方を示しています。提供されたリファレンス情報ではDom\Documentクラスに所属とありますが、PHP 8のDOM拡張では実際にはDom\Nodeクラスのメソッドですので注意が必要です。このメソッドは、2つのDOMノードがメモリ上で全く同じオブジェクト(同じインスタンス)であるかを判定します。ノードの内容や属性が同じであっても、別々に作成されたノードは異なるオブジェクトとみなされ、isSameNodeはfalseを返します。DOMツリーから取得したノードが、すでに存在するノードと同じインスタンスを指す場合にtrueとなります。引数にnullを渡した場合は常にfalseを返しますので、意図しない挙動に注意してください。このメソッドは、ノードが本当に同一のインスタンスであるかを確認する際に活用できます。