【PHP8.x】Dom\EntityReference::contains()メソッドの使い方
containsメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『containsメソッドは、引数で指定されたノードが、このエンティティ参照ノードの子孫であるかどうかを判定するために実行するメソッドです。このメソッドは、DOMツリーにおけるノード間の階層的な関係、つまり親子や先祖子孫の関係を調べる際に使用されます。メソッドを呼び出したエンティティ参照ノードを基準とし、引数に渡されたノードがその直接の子、孫、あるいはそれ以降の深い階層に存在する場合にtrueを返します。引数のノードが子孫でない場合や、引数がnullの場合はfalseを返します。ここで重要な点は、比較対象として自分自身のノードを指定した場合も子孫と見なされ、trueが返されることです。この機能を利用することで、XMLやHTMLドキュメントの構造をプログラムで解析する際に、ある特定の要素が別の要素の内部に含まれているかどうかを簡単に、そして確実に確認することができます。
構文(syntax)
1public Dom\Node::contains(?Dom\Node $other): bool
引数(parameters)
?Dom\Node $other
- ?Dom\Node $other: 比較対象となる Dom\Node オブジェクト。null の場合もあります。
戻り値(return)
bool
このメソッドは、指定した要素がこのDom\EntityReference内に存在するかどうかを示す真偽値(trueまたはfalse)を返します。
サンプルコード
PHPで配列に値が含まれるか調べる
1<?php 2 3declare(strict_types=1); 4 5/** 6 * 指定された配列に、特定の値が含まれているかどうかを確認します。 7 * 8 * この関数は、PHPで配列内に特定の要素が存在するかを調べる 9 * 最も一般的な方法である `in_array()` を使用します。 10 * 11 * @param mixed $needle 検索する値。 12 * @param array $haystack 検索対象の配列。 13 * @return bool 値が配列内に存在すれば true、そうでなければ false を返します。 14 */ 15function checkIfValueExistsInArray(mixed $needle, array $haystack): bool 16{ 17 // in_array() は、配列内に値が存在するかどうかをチェックする組み込み関数です。 18 // 第3引数を true に設定すると、型も比較する厳密なチェックが行われます。 19 return in_array($needle, $haystack, true); 20} 21 22// サンプルデータとして果物の配列を定義します 23$fruits = ['apple', 'banana', 'orange']; 24 25// --- ケース1: 配列に値が存在する場合 --- 26$searchValue1 = 'banana'; 27 28if (checkIfValueExistsInArray($searchValue1, $fruits)) { 29 echo "'{$searchValue1}' は配列内に存在します。\n"; 30} else { 31 echo "'{$searchValue1}' は配列内に存在しません。\n"; 32} 33 34// --- ケース2: 配列に値が存在しない場合 --- 35$searchValue2 = 'grape'; 36 37if (checkIfValueExistsInArray($searchValue2, $fruits)) { 38 echo "'{$searchValue2}' は配列内に存在します。\n"; 39} else { 40 echo "'{$searchValue2}' は配列内に存在しません。\n"; 41} 42 43// --- ケース3: 型が異なる場合(厳密なチェック) --- 44$numbers = [1, 2, '3', 4]; 45$searchNumber = 3; // '3' (文字列)ではなく 3 (整数) 46 47if (checkIfValueExistsInArray($searchNumber, $numbers)) { 48 echo "{$searchNumber} (整数) は配列内に存在します。\n"; 49} else { 50 // in_arrayの第3引数がtrueのため、型が違う '3' とは一致しない 51 echo "{$searchNumber} (整数) は配列内に存在しません。\n"; 52} 53 54?>
このPHPサンプルコードは、配列の中に特定の要素が含まれているかどうかを確認する基本的な方法を示しています。コードの中心となるのは、PHPに標準で組み込まれているin_array()関数です。
このin_array()関数は、第1引数に検索したい値、第2引数に検索対象の配列を指定すると、値が配列内に存在するかどうかを判定します。そして、結果を真偽値(bool型)で返します。値が見つかればtrue、見つからなければfalseが返されます。
サンプルコードでは、in_array()の第3引数にtrueを指定しています。これは「厳密な比較」を行うための設定で、値だけでなくデータ型まで完全に一致するかどうかをチェックします。この設定により、例えば数値の3と文字列の'3'は、値が同じでも型が違うため、別物として扱われます。
コード内の実行例では、この仕組みがよくわかります。配列に存在する'banana'を検索した場合は「存在します」と表示されます。一方、存在しない'grape'を検索すると「存在しません」と表示されます。最後の例では、厳密な比較のため、整数の3は配列内の文字列'3'とは一致しないと判断され、「存在しません」という結果になります。このように、in_array()関数は配列の要素を検索する際に非常に便利です。
リファレンス情報にある contains はXML文書を扱うための専門的なメソッドであり、サンプルコードで示されている配列の要素検索とは目的が異なります。配列内に特定の要素が含まれるかを確認するには in_array() 関数を使用します。この関数で最も重要な注意点は、第3引数に true を指定することです。これにより、値とデータ型が両方とも一致する場合のみ true を返す厳密な比較が行われます。例えば、数値の 3 と文字列の '3' を区別できるため、予期せぬバグを防ぎ、コードの安全性を高めることができます。特別な理由がない限り、この厳密な比較を有効にすることが推奨されます。
PHP Dom\EntityReference::contains でノード包含を判定する
1<?php 2 3/** 4 * Dom\EntityReference::contains の使用例を示す関数 5 * 6 * この関数は、XMLドキュメント内のエンティティ参照ノードが、 7 * 他の特定のノードを子孫として含んでいるかどうかを判定します。 8 */ 9function demonstrateEntityReferenceContains(): void 10{ 11 // エンティティ参照 (&writer;) を含むXML文字列を定義します。 12 // <!DOCTYPE> でエンティティを宣言しています。 13 $xmlString = <<<XML 14 <?xml version="1.0" encoding="UTF-8"?> 15 <!DOCTYPE author [ 16 <!ENTITY writer "<span>J. R. R. Tolkien</span>"> 17 ]> 18 <author> 19 <name>&writer;</name> 20 <genre>Fantasy</genre> 21 </author> 22 XML; 23 24 // DOMDocumentオブジェクトを生成します。 25 $doc = new DOMDocument(); 26 27 // XMLを読み込みます。 28 // オプションを指定しないことで、エンティティ参照がノードとして保持されます。 29 $doc->loadXML($xmlString); 30 31 // XPathを使って各ノードを正確に取得します。 32 $xpath = new DOMXPath($doc); 33 34 // 1. <name>タグ内のエンティティ参照ノード (&writer;) を取得します。 35 // これは Dom\EntityReference のインスタンスです。 36 /** @var Dom\EntityReference|null $entityRefNode */ 37 $entityRefNode = $xpath->query('//name/child::node()[1]')->item(0); 38 39 // 2. エンティティ参照の *内部* にある <span> ノードを取得します。 40 /** @var Dom\Node|null $insideNode */ 41 $insideNode = $xpath->query('//span')->item(0); 42 43 // 3. エンティティ参照の *外部* にある <genre> ノードを取得します。 44 /** @var Dom\Node|null $outsideNode */ 45 $outsideNode = $xpath->query('//genre')->item(0); 46 47 // ノードが正しく取得できたか確認します。 48 if ($entityRefNode instanceof Dom\EntityReference && $insideNode && $outsideNode) { 49 // --- contains() メソッドの実行例 --- 50 51 // 例1: エンティティ参照ノードが、その内部のノード (<span>) を含んでいるか確認します。 52 // 結果は true になります。 53 $result1 = $entityRefNode->contains($insideNode); 54 echo 'エンティティ参照は内部の <span> ノードを含んでいますか?' . PHP_EOL; 55 var_dump($result1); // bool(true) 56 echo PHP_EOL; 57 58 // 例2: エンティティ参照ノードが、その外部のノード (<genre>) を含んでいるか確認します。 59 // 結果は false になります。 60 $result2 = $entityRefNode->contains($outsideNode); 61 echo 'エンティティ参照は外部の <genre> ノードを含んでいますか?' . PHP_EOL; 62 var_dump($result2); // bool(false) 63 echo PHP_EOL; 64 65 // 例3: ノードが自分自身を含んでいるか確認します。 66 // 結果は true になります。 67 $result3 = $entityRefNode->contains($entityRefNode); 68 echo 'エンティティ参照は自分自身を含んでいますか?' . PHP_EOL; 69 var_dump($result3); // bool(true) 70 71 } else { 72 echo '必要なノードの取得に失敗しました。'; 73 } 74} 75 76// 関数を実行して結果を表示します。 77demonstrateEntityReferenceContains();
Dom\EntityReference::containsメソッドは、あるエンティティ参照ノードが、引数で指定された別のノードを子孫として含んでいるかどうかを判定します。XMLやHTMLドキュメント内でのノードの親子関係や包含関係を調べる際に使用します。
引数には、子孫として含まれているか確認したいノード (Dom\Nodeオブジェクト) を渡します。戻り値は真偽値 (bool) であり、引数のノードが子孫として含まれていればtrue、そうでなければfalseを返します。
サンプルコードでは、&writer;というエンティティ参照ノードを取得しています。このエンティティ参照は、内部に<span>タグを持っています。contains()メソッドを使って、このエンティティ参照ノードが内部の<span>ノードを含んでいるか確認すると、結果はtrueとなります。一方、エンティティ参照の外部にある<genre>ノードを指定した場合は、子孫関係にないためfalseが返されます。また、ノードが自分自身を含むかどうかも判定でき、その場合はtrueを返します。このように、特定のノードがエンティティ参照のスコープ内に存在するかを正確に確認できます。
Dom\EntityReference::containsメソッドは、あるエンティティ参照ノードが、指定したノードを子孫として含んでいるかを判定します。XMLを読み込む際、エンティティ参照が展開されない設定(loadXMLのデフォルト動作)であることが前提です。このメソッドは、直接の子だけでなく孫以降の深い階層にあるノードも判定対象とし、自分自身を指定した場合はtrueを返します。引数にnullを渡した場合はfalseが返されます。また、XPathなどでノードを取得する際は、対象が存在せずnullが返る可能性があるため、containsメソッドを呼び出す前に必ずノードの存在チェックを行うことが安全なコードにつながります。