Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【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などの他のノード型とは動作が異なる点を認識しておくことが、コードを正しく利用する上で大切です。

関連コンテンツ

関連プログラミング言語