【PHP8.x】Dom\Text::contains()メソッドの使い方
containsメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
containsメソッドは、Dom\Textオブジェクトが、指定された別のDom\NodeオブジェクトをDOMツリー上で含んでいるかどうかを判定するメソッドです。このメソッドは、PHPのDOM拡張機能の一部であり、Webページの構造をプログラムで操作する際に利用されるDOMツリー内のノード間の関係性を確認するために使用されます。
具体的には、containsメソッドは、メソッドを呼び出したDom\Textインスタンスが、引数として渡されたDom\Nodeインスタンスの「祖先」であるか、または「引数のノードそのもの」である場合に真(true)を返します。Dom\Textクラスはテキストノードを表し、HTMLやXMLドキュメント内の実際のテキストコンテンツを扱います。DOMの仕様上、テキストノードは子ノードを持つことができません。
このため、containsメソッドがtrueを返すのは、引数として渡されたDom\Nodeが、まさにそのcontainsメソッドを呼び出したDom\Textノード自身である場合のみです。それ以外の場合、例えば引数のノードが呼び出し元のDom\Textノードとは異なるノードである、または親子関係にない場合には、偽(false)を返します。
このメソッドは、判定の対象となるDom\Nodeオブジェクトを一つ引数として受け取ります。戻り値はブール値で、含まれていると判定された場合はtrue、そうでない場合はfalseです。主に、特定のテキストノードが意図した通りのオブジェクトであるかを確認するなど、DOMツリー内でノード間の厳密な同一性や限定的な関係性を確認する際に役立ちます。
構文(syntax)
1<?php 2$dom = new DOMDocument(); 3$textNode = $dom->createTextNode("Hello, PHP World!"); 4$isContained = $textNode->contains("World");
引数(parameters)
?Dom\Node $other
- ?Dom\Node $other: 比較対象となるDOMノード
戻り値(return)
bool
指定された文字列がDom\Textオブジェクトのコンテンツに含まれているかどうかを示す真偽値(trueまたはfalse)を返します。
サンプルコード
PHP Dom\Text::contains() によるノード包含チェック
1<?php 2 3// 新しいDOMドキュメントを作成します。 4$dom = new Dom\Document(); 5 6// ドキュメントにルート要素(例: <p>)を作成し追加します。 7$paragraph = $dom->createElement('p'); 8$dom->appendChild($paragraph); 9 10// テキストノードを作成し、<p>要素に追加します。 11// Dom\Text::contains() メソッドはこの $mainTextNode を対象に動作します。 12$mainTextNode = $dom->createTextNode('Hello, '); 13$paragraph->appendChild($mainTextNode); 14 15// 別のテキストノードを作成し、同じ<p>要素に追加します。 16$childTextNode = $dom->createTextNode('World!'); 17$paragraph->appendChild($childTextNode); 18 19// 第3のテキストノードを作成します。これはDOMツリーのどこにも追加しません。 20$unconnectedTextNode = $dom->createTextNode('This is separate.'); 21 22echo "--- Dom\\Text::contains() のデモンストレーション ---" . PHP_EOL . PHP_EOL; 23 24// ケース1: テキストノードがそれ自身を含んでいるかチェックします。 25// DOMの規約では、ノードはそれ自身を含んでいるとみなされます。 26$isSelfContained = $mainTextNode->contains($mainTextNode); 27echo "mainTextNode はそれ自身を含んでいますか? " . ($isSelfContained ? 'はい' : 'いいえ') . PHP_EOL; // 期待値: はい 28 29echo PHP_EOL; 30 31// ケース2: テキストノードが別のDOMツリーの子孫であるテキストノードを含んでいるかチェックします。 32// Dom\Textノードはリーフノードであり、通常は他のDom\Nodeを子孫として含みません。 33// Dom\Textノードは文字データのみを含みます。 34$isChildTextContained = $mainTextNode->contains($childTextNode); 35echo "mainTextNode ('Hello, ') は childTextNode ('World!') を含んでいますか? " . ($isChildTextContained ? 'はい' : 'いいえ') . PHP_EOL; // 期待値: いいえ 36 37echo PHP_EOL; 38 39// ケース3: テキストノードがDOMツリーに接続されていない別のテキストノードを含んでいるかチェックします。 40$isUnconnectedContained = $mainTextNode->contains($unconnectedTextNode); 41echo "mainTextNode は unconnectedTextNode を含んでいますか? " . ($isUnconnectedContained ? 'はい' : 'いいえ') . PHP_EOL; // 期待値: いいえ 42 43echo PHP_EOL; 44 45// ケース4: テキストノードがその親要素を含んでいるかチェックします。 46// 子ノードは親ノードを含むことはできません。 47$isParentContained = $mainTextNode->contains($paragraph); 48echo "mainTextNode は親要素 'p' を含んでいますか? " . ($isParentContained ? 'はい' : 'いいえ') . PHP_EOL; // 期待値: いいえ 49 50echo PHP_EOL; 51 52// 参考: 通常の要素ノードでの contains() の動作 (Dom\Text::contains とは異なる振る舞いを示します) 53echo "--- 参考: Dom\\Element::contains() の動作 ---" . PHP_EOL . PHP_EOL; 54$isTextNodeContainedByElement = $paragraph->contains($mainTextNode); 55echo "親要素 'p' は mainTextNode を含んでいますか? " . ($isTextNodeContainedByElement ? 'はい' : 'いいえ') . PHP_EOL; // 期待値: はい 56 57?>
Dom\Text::containsは、PHP 8から利用できるDOM操作のためのメソッドです。このメソッドはDom\Textクラスに属しており、あるテキストノードが、引数に指定された別のDom\Nodeオブジェクトを含んでいるかを確認し、その結果を真偽値(bool)で返します。
引数$otherには、包含関係をチェックしたいDom\Nodeを指定します。この引数は省略可能であり、nullが渡された場合はfalseが返されます。
Dom\Textノードは、XMLやHTMLの構造における文字データ部分を担当する「リーフノード」です。これは、他のDom\Nodeを子孫として持つことができないという特性を持っています。そのため、このcontainsメソッドの挙動は、子要素を持つことができるDom\Elementなどのノードとは異なります。
具体的には、テキストノードはDOMの規約により、それ自身を含んでいるとみなされますので、$mainTextNode->contains($mainTextNode)はtrueを返します。しかし、Dom\Textノードは子を持たないため、別のテキストノードや、自身の親要素、あるいはDOMツリーに接続されていない他のノードを含んでいるかをチェックした場合は、常にfalseが返されます。
このメソッドは、テキストノードの厳密な階層的包含関係を判定する際に利用されます。
このサンプルコードは、Dom\Text::contains()メソッドの動作を示しています。Dom\Textノードはテキストデータのみを持つため、基本的に他の要素やテキストノードを子孫として含むことはありません。このメソッドがtrueを返すのは、引数に自身のノードを指定した場合のみです。たとえ同じ親要素の子であっても、自身以外のノードに対してはほとんどの場合でfalseを返します。これは、要素ノードが子孫ノードを含むかを確認するDom\Element::contains()のような一般的なメソッドの挙動とは大きく異なりますので、混同しないように注意が必要です。このメソッドは、DOMツリーにおけるテキストノードの特殊な包含関係を理解するために活用してください。
PHP Dom\Text::contains の動作確認
1<?php 2 3use Dom\Document; 4use Dom\Element; 5use Dom\Text; 6use Dom\Node; // Dom\Text::contains の引数型ヒントで使用 7 8/** 9 * Dom\Text::contains メソッドの動作を示すサンプル関数。 10 * 11 * このメソッドは、Dom\Text ノードが指定されたノードを子孫として含むかどうかを判断します。 12 * Dom\Text ノードは構造上、子ノードを持つことができないため、常に false を返します。 13 * システムエンジニアを目指す初心者向けに、基本的なDOM操作とメソッドの使用方法を示します。 14 */ 15function demonstrateDomTextContains(): void 16{ 17 // 1. Dom\Document オブジェクトを作成し、簡単なHTMLをロード 18 // PHP 8のDom拡張では、クラスは Dom\ 名前空間にあります。 19 $dom = new Document(); 20 21 // HTMLパース時の警告を抑制し、処理後に元に戻す 22 $previousUseErrors = libxml_use_internal_errors(true); 23 $dom->loadHTML('<p>Hello <span>World</span>!</p>'); 24 libxml_use_internal_errors($previousUseErrors); 25 26 // 2. 目的の Dom\Text ノードと Dom\Element ノードを取得 27 // <p>要素内の最初のテキストノード("Hello ")を取得する例 28 /** @var Element|null $paragraph */ 29 $paragraph = $dom->getElementsByTagName('p')->item(0); 30 31 if (!$paragraph) { 32 echo "エラー: <p> 要素が見つかりませんでした。\n"; 33 return; 34 } 35 36 /** @var Text|null $helloTextNode */ 37 $helloTextNode = null; 38 /** @var Element|null $spanElement */ 39 $spanElement = null; 40 /** @var Text|null $exclamationTextNode */ 41 $exclamationTextNode = null; 42 43 // <p>要素の子ノードをループして、必要なノードを特定 44 foreach ($paragraph->childNodes as $childNode) { 45 if ($childNode instanceof Text && str_contains($childNode->textContent, 'Hello')) { 46 $helloTextNode = $childNode; // "Hello " テキストノード 47 } elseif ($childNode instanceof Element && $childNode->tagName === 'span') { 48 $spanElement = $childNode; // <span>World</span> 要素 49 } elseif ($childNode instanceof Text && str_contains($childNode->textContent, '!')) { 50 $exclamationTextNode = $childNode; // "!" テキストノード 51 } 52 } 53 54 echo "--- Dom\\Text::contains() の動作サンプル ---\n"; 55 56 if (!$helloTextNode) { 57 echo "エラー: 'Hello ' テキストノードが見つかりませんでした。\n"; 58 return; 59 } 60 61 // Dom\Text::contains() メソッドの呼び出しと結果の出力 62 // Dom\Text ノードは子を持てないため、contains メソッドは常に false を返します。 63 64 // ケース1: 別のテキストノードを比較対象として渡す 65 if ($exclamationTextNode) { 66 $result1 = $helloTextNode->contains($exclamationTextNode); 67 echo "メインテキストノード ('" . $helloTextNode->textContent . "') が別のテキストノード ('" . $exclamationTextNode->textContent . "') を含むか?: " . ($result1 ? 'true' : 'false') . "\n"; 68 // 期待値: false (Textノードは子を持てないため) 69 } 70 71 // ケース2: 要素ノードを比較対象として渡す 72 if ($spanElement) { 73 $result2 = $helloTextNode->contains($spanElement); 74 echo "メインテキストノード ('" . $helloTextNode->textContent . "') が要素ノード (<span>) を含むか?: " . ($result2 ? 'true' : 'false') . "\n"; 75 // 期待値: false (Textノードは子を持てないため) 76 } 77 78 // ケース3: null を比較対象として渡す 79 // 引数が ?Dom\Node $other のため、nullも許容されます。 80 $result3 = $helloTextNode->contains(null); 81 echo "メインテキストノード ('" . $helloTextNode->textContent . "') が null を含むか?: " . ($result3 ? 'true' : 'false') . "\n"; 82 // 期待値: false (Textノードは子を持てないため) 83 84 echo "\n補足: Dom\\Text ノードは、HTML/XMLのドキュメント構造上、子ノードを持つことができません。\n"; 85 echo "したがって、Dom\\Text::contains() メソッドは、引数が何であっても常に false を返します。\n"; 86} 87 88// サンプル関数を実行 89demonstrateDomTextContains();
PHP 8のDom拡張機能に属するDom\Text::contains()メソッドは、特定のDom\Textノードが、引数として渡された別のDom\Nodeを子孫として含むかどうかを判定するメソッドです。引数$otherは?Dom\Node型で、比較対象となるノード、またはnullを受け入れます。戻り値はbool型で、含む場合はtrue、含まない場合はfalseを返します。
しかし、HTMLやXMLのドキュメント構造において、Dom\Textノードは純粋なテキストコンテンツのみを保持し、構造上、子ノードを持つことはできません。このため、Dom\Text::contains()メソッドは、引数にどのようなDom\Nodeオブジェクトやnullが渡されたとしても、常にfalseを返します。
サンプルコードでは、<p>Hello <span>World</span>!</p>というHTMLから「Hello 」テキストノードを取得し、これに対して別のテキストノード、<span>要素ノード、そしてnullを引数としてcontains()メソッドを呼び出しています。結果は全てのケースでfalseとなり、Dom\Textノードが子ノードを持たないというDOMの基本的な構造と、それに基づくこのメソッドの挙動が明確に示されています。システムエンジニアを目指す上では、このように特定のノードタイプの特性を理解し、メソッドの動作を正確に把握することが重要です。
Dom\Text::contains()メソッドは、テキストノードが指定されたノードを子孫として含むかを確認します。しかし、HTMLやXMLの構造上、Dom\Textノードは子ノードを持つことができません。したがって、このメソッドは引数にどのようなDom\Nodeオブジェクト(またはnull)が渡されたとしても、常にfalseを返します。初心者がノード間の親子関係を調べたい場合、テキストノードのこの特殊性を理解せずに使用すると、期待と異なる結果となる可能性がありますのでご注意ください。Dom\Elementなどの他のノード型とは動作が異なる点を認識しておくことが、コードを正しく利用する上で大切です。