【PHP8.x】DOMNotation::contains()メソッドの使い方
containsメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
containsメソッドは、指定したノードが現在処理しているDOMNotationノードの子孫であるかどうかを判定するメソッドです。このメソッドは、すべてのDOMノードの基本となる親クラスDOMNodeから継承された機能です。一般的に、あるノードに対してcontainsメソッドを使用すると、引数で渡された別のノードが、そのノードの階層構造内、つまり子や孫ノードとして含まれているかを調べることができます。含まれている場合はtrueを、含まれていない場合はfalseを返します。しかし、DOMの仕様上、DOMNotationノードは子ノードを持つことができません。これは、DOMNotationがDTD(文書型定義)内で宣言された記法そのものを表すための特殊なノードであり、子要素を持つことを想定していないためです。したがって、DOMNotationオブジェクトに対してこのメソッドを呼び出した場合、引数にどのようなノードを指定しても、そのノードが子孫であることはありえないため、結果は常にfalseとなります。このメソッドはクラスの継承関係によって存在しますが、DOMNotationの文脈においては実質的に使用される場面はありません。
構文(syntax)
1<?php 2$xmlString = <<<XML 3<?xml version="1.0" encoding="UTF-8"?> 4<!DOCTYPE root [ 5 <!NOTATION notation1 PUBLIC "public_id_1"> 6 <!NOTATION notation2 PUBLIC "public_id_2"> 7]> 8<root/> 9XML; 10 11$doc = new DOMDocument(); 12$doc->validateOnParse = true; 13$doc->loadXML($xmlString); 14 15// DOMNotation オブジェクトを取得 16$notation = $doc->doctype->notations->getNamedItem('notation1'); 17$otherNode = $doc->doctype->notations->getNamedItem('notation2'); 18 19// $notation が $otherNode を子孫として含むか判定します。 20$isContained = $notation->contains($otherNode); 21 22var_dump($isContained); 23?>
引数(parameters)
?DOMNode $other
- ?DOMNode $other: 比較対象となるDOMNodeオブジェクト
戻り値(return)
bool
指定された文字列がDOMNotationオブジェクト内に含まれているかどうかを真偽値(trueまたはfalse)で返します。
サンプルコード
PHPで配列に値が含まれるか確認する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * 指定された値が配列内に存在するかどうかを確認します。 7 * 8 * この関数は、PHPの組み込み関数 in_array() のラッパーとして機能し、 9 * 配列内に特定の要素が含まれているか(contains)をチェックする一般的な方法を示します。 10 * 11 * @param array<int|string, mixed> $haystack 検索対象の配列。 12 * @param mixed $needle 検索する値。 13 * @return bool 値が配列内に見つかった場合は true、それ以外は false を返します。 14 */ 15function doesArrayContainValue(array $haystack, mixed $needle): bool 16{ 17 // in_array()関数は、配列に値が存在するかどうかをチェックします。 18 // 第3引数に true を指定すると、型も比較する厳密なチェック (===) を行います。 19 // PHP 8以降では、この厳密なチェックが推奨されます。 20 return in_array($needle, $haystack, true); 21} 22 23// チェック対象の配列を定義します。 24$fruits = ['apple', 'banana', 'orange']; 25 26// --- ケース1: 配列に存在する値を確認 --- 27$value1 = 'banana'; 28if (doesArrayContainValue($fruits, $value1)) { 29 echo "'{$value1}' は配列に含まれています。" . PHP_EOL; 30} else { 31 echo "'{$value1}' は配列に含まれていません。" . PHP_EOL; 32} 33 34// --- ケース2: 配列に存在しない値を確認 --- 35$value2 = 'grape'; 36if (doesArrayContainValue($fruits, $value2)) { 37 echo "'{$value2}' は配列に含まれています。" . PHP_EOL; 38} else { 39 echo "'{$value2}' は配列に含まれていません。" . PHP_EOL; 40} 41 42// --- ケース3: 型が異なる値を確認(厳密なチェック) --- 43$numbers = [10, 20, '30']; 44$value3 = 30; // データ型は integer 45if (doesArrayContainValue($numbers, $value3)) { 46 echo "数値の {$value3} は配列に含まれています。" . PHP_EOL; 47} else { 48 // 配列内の '30' は文字列型なので、厳密な比較では false となります。 49 echo "数値の {$value3} は配列に含まれていません。(文字列の '30' は存在します)" . PHP_EOL; 50} 51 52?>
このPHPサンプルコードは、配列の中に特定のデータが含まれているかどうかを確認する方法を解説しています。そのために doesArrayContainValue という独自の関数を定義し、具体的な使用例を示しています。
この関数は2つの引数を取ります。第1引数の $haystack は検索対象となる配列で、第2引数の $needle はその配列の中から探したい値です。関数の内部では、PHPに標準で用意されている in_array() 関数を呼び出しています。このコードの重要な点は、in_array() の第3引数に true を指定していることです。これにより、値が一致するかに加えて、データ型(例えば数値と文字列の違い)まで一致するかどうかを厳密に比較します。
関数の戻り値は bool 型(ブール型)であり、$needle で指定した値が配列内に見つかった場合は true を、見つからなかった場合は false を返します。サンプルコードの最後の例では、数値の 30 と文字列の '30' が厳密に区別されるため、検索結果が false となることを示しており、正確なデータ検索におけるこの手法の有効性がわかります。
このコードの最も重要な点は、in_array関数の第3引数にtrueを指定し、厳密な型比較を行っていることです。これを指定しない場合、例えば数値の30と文字列の'30'が同じものとして扱われ、意図しない動作の原因となります。特にユーザー入力など、データ型が保証されない値を扱う際は、バグを防ぐためにこの厳密なチェックが不可欠です。サンプルコードのように、常に厳密なチェックを行う関数を独自に定義し、プロジェクト内で統一して使用することは、コードの安全性と可読性を高めるための良い実践方法と言えます。
PHP DOMNotation contains メソッドの使い方
1<?php 2 3/** 4 * DOMNotation::contains メソッドの使用例 5 * 6 * このスクリプトは、XMLのDOCTYPE宣言からDOMNotationオブジェクトを取得し、 7 * その `contains` メソッドが他のDOMNodeオブジェクトを含むかどうかをどのように判定するかを示します。 8 * DOMNotation は子ノードを持たない特殊なDOMNodeであるため、 9 * 基本的に自身以外を「含む」と判定することはありません。 10 */ 11 12// XML ドキュメントを定義します。DOCTYPE宣言にNOTATIONを含めます。 13$xmlString = <<<XML 14<!DOCTYPE doc [ 15 <!NOTATION myNotation PUBLIC "my-public-id" "my-system-id"> 16 <!ELEMENT doc EMPTY> 17]> 18<doc/> 19XML; 20 21// DOMDocument オブジェクトを作成し、XMLをロードします。 22$dom = new DOMDocument(); 23$dom->loadXML($xmlString); 24 25$notation = null; 26// DOCTYPE宣言が存在し、かつnotationリストが存在する場合に処理を続行します。 27if ($dom->doctype && $dom->doctype->notations) { 28 // DOMNamedNodeMap はイテレート可能なオブジェクトなので、foreachでnotationを取得します。 29 foreach ($dom->doctype->notations as $n) { 30 if ($n instanceof DOMNotation) { 31 $notation = $n; 32 break; // 最初のDOMNotationオブジェクトを見つけたらループを終了します。 33 } 34 } 35} 36 37// DOMNotation オブジェクトが正常に取得できた場合のみ処理を実行します。 38if ($notation) { 39 echo "DOMNotation オブジェクト '{$notation->nodeName}' を取得しました。\n\n"; 40 41 // 1. DOMNotation オブジェクト自身が、そのオブジェクトに含まれるかチェックします。 42 // DOMNode::contains の一般的な挙動として、自身は自身に含まれると判定されます。 43 $containsSelf = $notation->contains($notation); 44 echo "DOMNotation オブジェクトは自身を含みますか?: " . ($containsSelf ? 'はい' : 'いいえ') . "\n"; 45 46 // 2. XMLドキュメントのルート要素が、DOMNotation オブジェクトに含まれるかチェックします。 47 // DOMNotation は階層構造の子ノードを持たないため、他のDOMNodeを含むことはありません。 48 $rootElement = $dom->documentElement; // <doc/> 要素 49 $containsRootElement = $notation->contains($rootElement); 50 echo "DOMNotation オブジェクトはルート要素 ({$rootElement->nodeName}) を含みますか?: " . ($containsRootElement ? 'はい' : 'いいえ') . "\n"; 51 52 // 3. 新しく作成したテキストノードが、DOMNotation オブジェクトに含まれるかチェックします。 53 $textNode = $dom->createTextNode("サンプルテキスト"); 54 $containsTextNode = $notation->contains($textNode); 55 echo "DOMNotation オブジェクトはテキストノードを含みますか?: " . ($containsTextNode ? 'はい' : 'いいえ') . "\n"; 56 57} else { 58 echo "XMLドキュメントからDOMNotationオブジェクトを取得できませんでした。\n"; 59}
PHP 8のDOMNotation::containsメソッドは、現在のDOMNotationオブジェクトが、引数に指定されたDOMNodeオブジェクトを含んでいるかどうかを判定するために使用されます。引数$otherには、含まれているかを調べたい別のDOMNodeオブジェクトを指定します。このメソッドはブール値(trueまたはfalse)を返し、もし$otherが現在のDOMNotationオブジェクトの直接的または間接的な子孫であればtrueを、そうでなければfalseを返します。
ただし、DOMNotationはXMLのDOCTYPE宣言内で定義される特殊なノードであり、DOMツリーにおいて子ノードを持つことはありません。そのため、このcontainsメソッドは一般的なDOMNodeクラスの実装とは異なり、基本的には現在のDOMNotationオブジェクト自身が引数として渡された場合のみtrueを返します。
サンプルコードでは、DOMNotationオブジェクト自身を引数に渡した際にはtrueが返される一方、XMLドキュメントのルート要素や新しく作成したテキストノードなど、他のDOMNodeオブジェクトを渡した際にはfalseが返されることが示されています。これは、DOMNotationが自身以外のノードを子として含まず、DOMツリー上の親子関係を持たないという特性を反映した挙動です。
DOMNotationはXMLの<!NOTATION>宣言を表す特殊なノードで、通常のDOMNodeとは異なり子ノードを持ちません。そのため、containsメソッドは指定されたノードがレシーバーオブジェクトの子孫であるかを判定しますが、DOMNotationでは基本的に自身以外を含むことはありません。したがって、$notation->contains($notation)のように自身を引数に指定した場合のみtrueが返り、その他のノード(たとえドキュメント内の他の要素であっても)を指定した場合は常にfalseが返る点に注意が必要です。XMLドキュメントにDOCTYPE宣言やNOTATIONが含まれない場合、DOMNotationオブジェクトの取得に失敗する可能性がありますので、サンプルコードのようにnullチェックを行うことが安全な利用に繋がります。
DOMNotation::contains でノード包含を判定する
1<?php 2 3// DOMNotation::contains メソッドのサンプルコード 4// このメソッドは、DTD (Document Type Definition) 内の NOTATION ノードが、 5// 指定されたDOMノードを含むかどうかをチェックします。 6// NOTATIONノードは通常子ノードを持たないため、$otherがNOTATIONノード自身の場合のみtrueを返します。 7// この機能は、XMLパーシングのより高度なシナリオで使用されます。 8 9/** 10 * DOMNotation::contains メソッドの使用例を示します。 11 * 12 * @param string $xmlString DTD (Document Type Definition) 定義を含むXML文字列 13 * @return void 14 */ 15function demonstrateDomNotationContains(string $xmlString): void 16{ 17 $dom = new DOMDocument(); 18 // XMLをロードし、DTDが解析されるようにする 19 $dom->loadXML($xmlString); 20 21 $doctype = $dom->doctype; 22 23 // ドキュメントにDTDがあり、NOTATIONが定義されている場合 24 if ($doctype && $doctype->notations) { 25 /** @var DOMNotation|null $gifNotation 特定のNOTATIONノードを見つけるための変数 */ 26 $gifNotation = null; 27 foreach ($doctype->notations as $notation) { 28 // 例として、名前が "gif" のNOTATIONノードを検索 29 if ($notation instanceof DOMNotation && $notation->nodeName === 'gif') { 30 $gifNotation = $notation; 31 break; 32 } 33 } 34 35 if ($gifNotation) { 36 echo "DOMNotation '{$gifNotation->nodeName}' を取得しました。\n\n"; 37 38 // 1. DOMNotation自身との比較 39 // 指定ノードがDOMNotation自身の場合、trueを返す 40 $isSelfContained = $gifNotation->contains($gifNotation); 41 echo "NOTATIONが自分自身を含みますか?: " . ($isSelfContained ? 'true' : 'false') . " (期待値: true)\n"; 42 43 // 2. 異なるDOMNodeとの比較 44 // DOMNotationは通常子ノードを持たないため、異なるノードとの比較はfalseを返す 45 $dummyElement = $dom->createElement('dummy'); 46 $isOtherNodeContained = $gifNotation->contains($dummyElement); 47 echo "NOTATIONが異なるDOM要素を含みますか?: " . ($isOtherNodeContained ? 'true' : 'false') . " (期待値: false)\n"; 48 49 // 3. nullとの比較 50 // nullを渡すと常にfalseを返す 51 $isNullContained = $gifNotation->contains(null); 52 echo "NOTATIONがnullを含みますか?: " . ($isNullContained ? 'true' : 'false') . " (期待値: false)\n"; 53 54 } else { 55 echo "XML内に 'gif' という名前のNOTATIONノードが見つかりませんでした。\n"; 56 } 57 } else { 58 echo "XMLにDTDまたはNOTATION定義がありません。\n"; 59 } 60} 61 62// DTDとNOTATION定義を含むXML文字列の例 63$xmlContent = <<<XML 64<?xml version="1.0"?> 65<!DOCTYPE document [ 66<!NOTATION gif SYSTEM "image/gif"> 67<!NOTATION jpeg SYSTEM "image/jpeg"> 68<!ELEMENT document (data)*> 69<!ELEMENT data (#PCDATA)> 70<!ATTLIST data 71 image_type NOTATION (gif | jpeg) #IMPLIED 72> 73]> 74<document> 75 <data image_type="gif">Sample image data</data> 76</document> 77XML; 78 79// サンプル関数の実行 80demonstrateDomNotationContains($xmlContent); 81
PHPのDOMNotation::containsメソッドは、XMLドキュメントのDTD(Document Type Definition)内で定義される「NOTATIONノード」という特殊なノードが、特定のDOMノードを含むかどうかをチェックするために利用されます。
引数 $other には、確認したいDOMノードオブジェクト、またはnullを渡します。戻り値は真偽値のbool型で、含まれる場合はtrue、含まれない場合はfalseが返されます。
NOTATIONノードは、通常は他の要素のような子ノードを持たない特性があります。このため、このメソッドは、引数として渡された$otherが、チェック対象のNOTATIONノード自身である場合にのみtrueを返します。異なるDOMノードが渡された場合や、nullが渡された場合は、常にfalseを返します。
このメソッドは、XMLのDTD構造を詳細に調べたり、特定のNOTATION定義を検証したりするような、より高度なXML解析の場面で活用されます。
このDOMNotation::containsメソッドは、PHPの文字列検索で一般的に使われるcontainsとは異なり、XMLのDTD内で定義されるNOTATIONノード専用です。NOTATIONノードは通常子ノードを持たないため、引数にDOMNotationノード自身が渡された場合にのみtrueを返します。異なるDOMNodeやnullが渡された場合は常にfalseとなりますので、この特定の挙動を理解しておくことが重要です。本メソッドは、XMLのDTD定義を深く扱う専門的な場面で利用されることが多く、一般的なWebアプリケーション開発で直接使用する機会は少ないでしょう。