【PHP8.x】containsメソッドの使い方
containsメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
containsメソッドは、ある処理命令ノードが、引数で指定された別のノードを子孫として含んでいるかどうかを判定するメソッドです。このメソッドは、DOMProcessingInstructionオブジェクトから呼び出され、チェックしたいDOMNodeオブジェクトを引数として渡します。もし引数のノードが呼び出し元のノードの子、孫、あるいはそれ以下の階層に存在する子孫ノードであればtrueを返します。そうでなければfalseを返します。ノード自身も含まれると判定されるため、自分自身を引数に指定した場合もtrueが返されます。XMLやHTML文書の親子関係や包含関係をプログラムで確認する際に非常に便利で、特定の処理命令の範囲内に目的のノードが存在するかを効率的に調べることができます。戻り値は真偽値であり、引数にnullが渡された場合はfalseとなります。
構文(syntax)
1<?php 2// DOMドキュメントを準備 3$xml = '<?xml version="1.0" encoding="utf-8" ?> 4<root> 5 <?php-instruction data?> 6 <childNode /> 7</root>'; 8 9$doc = new DOMDocument(); 10$doc->loadXML($xml); 11 12// DOMProcessingInstruction ノードを取得 13$instructionNode = $doc->documentElement->childNodes->item(1); 14 15// 比較対象のノードを取得 16$childNode = $doc->getElementsByTagName('childNode')->item(0); 17 18// $instructionNode が $childNode を子孫として含んでいるか確認します 19$isContained = $instructionNode->contains($childNode); 20 21var_dump($isContained); 22?>
引数(parameters)
?DOMNode $other
- ?DOMNode $other: 比較対象となるDOMNodeオブジェクト。nullを指定することも可能。
戻り値(return)
bool
指定された文字列がDOMProcessingInstructionノードの値に含まれているかどうかを判定し、結果を真偽値(bool)で返します。
サンプルコード
PHP配列に値が含まれるかチェックする
1<?php 2 3/** 4 * 指定された値が配列内に存在するかどうかをチェックします。 5 * 6 * PHPの配列に特定の値が含まれているかを確認する最も一般的な方法は、 7 * `in_array()` 関数を使用することです。この関数は、配列内に値が見つかれば true を、 8 * 見つからなければ false を返します。 9 * 10 * @param array $haystack 検索対象の配列 11 * @param mixed $needle 検索する値 12 * @return void 13 */ 14function checkValueInArray(array $haystack, mixed $needle): void 15{ 16 // in_array() を使って配列内に値が存在するかをチェック 17 if (in_array($needle, $haystack, true)) { 18 // 第3引数を true にすると、型も比較する厳密なチェックになります (=== と同じ) 19 echo "配列に '{$needle}' は存在します。\n"; 20 } else { 21 echo "配列に '{$needle}' は存在しません。\n"; 22 } 23} 24 25// チェック対象の配列 26$fruits = ['apple', 'banana', 'orange', 'grape']; 27 28// ケース1: 配列に存在する値をチェック 29checkValueInArray($fruits, 'banana'); 30 31// ケース2: 配列に存在しない値をチェック 32checkValueInArray($fruits, 'melon'); 33 34// ケース3: 数値の配列でチェック 35$numbers = [1, 2, 3, 4, 5]; 36checkValueInArray($numbers, 3); 37 38// ケース4: 型が違う場合 (厳密なチェックのため false になる) 39$mixedArray = ['1', 2, '3']; 40checkValueInArray($mixedArray, 1); // 文字列の '1' はあるが、数値の 1 はない 41 42?>
このサンプルコードは、PHPの配列に特定の要素が含まれているかどうかを調べる方法を示しています。この処理には、PHPに標準で用意されている in_array() 関数が使われます。
in_array() 関数は、第1引数で指定した値が、第2引数の配列内に存在するかを判定します。値が見つかれば true を、見つからなければ false を返します。このコードの重要な点は、in_array() の第3引数に true を設定していることです。これにより、値とデータ型の両方が一致するかを厳密にチェックします。例えば、数値の 1 と文字列の '1' は異なるものとして扱われます。
コード内の checkValueInArray 関数は、この判定ロジックをまとめたものです。引数として検索対象の配列 $haystack と探したい値 $needle を受け取り、in_array() の結果に応じて「存在します」または「存在しません」というメッセージを表示します。この関数自体は特定の値を返さないため、戻り値の型は void となっています。
in_array()関数を使う上で最も重要な点は、第3引数にtrueを指定して厳密な比較を行うことです。この指定を省略すると、例えば数値の0と空文字列''が同じと判定されるなど、予期せぬ動作を引き起こす原因となります。バグを防ぐため、型まで含めて一致するかを常に確認するようにしましょう。また、この関数は配列の要素を一つずつ順番に調べるため、巨大な配列に対して繰り返し使用すると処理速度が低下する可能性があります。パフォーマンスが求められる場合は、値をキーにした連想配列を作成し、isset()で存在確認をする方が高速です。
DOMProcessingInstruction::contains の動作を確認する
1<?php 2 3/** 4 * DOMProcessingInstruction::contains の使用例を示します。 5 * 6 * このメソッドは、ある処理命令ノードが、引数で指定されたノードを 7 * 子孫として含んでいるかどうかを判定します。 8 * 9 * 処理命令ノード (例: <?php-stylesheet ... ?>) は子ノードを持てないため、 10 * このメソッドが true を返すのは、引数に自分自身のノードを指定した場合のみです。 11 */ 12function demonstrateDomProcessingInstructionContains(): void 13{ 14 // サンプルとなるXML文字列を定義します。 15 // `<?php-stylesheet ...?>` が処理命令(Processing Instruction)ノードです。 16 $xmlString = <<<XML 17<?xml version="1.0" encoding="UTF-8"?> 18<document> 19 <?php-stylesheet type="text/css" href="style.css"?> 20 <content> 21 <p>Hello, World!</p> 22 </content> 23</document> 24XML; 25 26 // DOMDocumentオブジェクトを作成し、XMLを読み込みます。 27 $dom = new DOMDocument(); 28 $dom->loadXML($xmlString); 29 30 // 比較の基準となる処理命令ノードを取得します。 31 // 親ノードの子ノード一覧を走査して見つけます。 32 $piNode = null; 33 foreach ($dom->documentElement->childNodes as $node) { 34 if ($node instanceof DOMProcessingInstruction) { 35 $piNode = $node; 36 break; 37 } 38 } 39 40 // 比較対象となる要素ノード (<p>) を取得します。 41 $paragraphNode = $dom->getElementsByTagName('p')->item(0); 42 43 // ノードが正しく取得できたか確認します。 44 if ($piNode === null || $paragraphNode === null) { 45 echo "必要なノードが見つかりませんでした。" . PHP_EOL; 46 return; 47 } 48 49 // --- contains() メソッドの検証 --- 50 51 // ケース1: 処理命令ノードが、他の要素ノードを含んでいるか確認します。 52 // 処理命令ノードは子を持てないため、結果は false になります。 53 $result1 = $piNode->contains($paragraphNode); 54 55 echo "処理命令ノードは <p> 要素を含んでいますか?" . PHP_EOL; 56 var_dump($result1); // 出力: bool(false) 57 58 echo PHP_EOL; 59 60 // ケース2: 処理命令ノードが、自分自身を含んでいるか確認します。 61 // ノード自身を比較した場合は true になります。 62 $result2 = $piNode->contains($piNode); 63 64 echo "処理命令ノードは自分自身を含んでいますか?" . PHP_EOL; 65 var_dump($result2); // 出力: bool(true) 66} 67 68// 関数を実行して結果を表示します。 69demonstrateDomProcessingInstructionContains();
PHPのDOMProcessingInstruction::contains()メソッドは、ある処理命令ノードが、引数で指定したノードを子孫として含んでいるかどうかを判定します。
このメソッドは、引数 $other に比較対象となるDOMNodeオブジェクトを受け取ります。判定結果は真偽値(bool)で返され、子孫として含んでいればtrue、そうでなければfalseとなります。
重要な点として、XMLの仕様では処理命令ノード(例: <?php-stylesheet ...?>)は子ノードを持つことができません。そのため、このcontains()メソッドがtrueを返すのは、引数に自分自身のノードインスタンスを指定した場合のみです。
サンプルコードでは、XML文書から処理命令ノード ($piNode) と段落要素 ($paragraphNode) を取得しています。まず、処理命令ノードが段落要素を含んでいるかをcontains()で確認しますが、子ノードを持てないため結果はfalseになります。次に、処理命令ノードが自分自身を含んでいるかを確認すると、これは常にtrueと判定されます。このメソッドは、ノードの親子関係を厳密に調べる際に利用されます。
DOMProcessingInstruction::contains()メソッドの利用には注意点があります。XMLの仕様上、処理命令ノード(例: <?php-stylesheet ...?>)は子ノードを持つことができません。そのため、このメソッドがtrueを返すのは、引数に自分自身のノードを指定した場合のみです。他の要素ノードなどを引数に渡した場合は、親子関係が存在しえないため必ずfalseが返ります。このメソッドを使う際は、一般的なノードの親子判定とは挙動が大きく異なる点を理解しておくことが重要です。また、contains()を呼び出す前に、対象の処理命令ノードがnullでないことを必ず確認する習慣をつけましょう。