【PHP8.x】Dom\HTMLElement::matches()メソッドの使い方
matchesメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
matchesメソッドは、Dom\HTMLElementクラスに属し、特定のHTML要素が指定されたCSSセレクタに一致するかどうかを判定するメソッドです。このメソッドは、呼び出し元のHTML要素自身が、引数として渡されるCSSセレクタ文字列の条件を満たすかどうかを評価します。
引数には、チェックしたい条件を記述したCSSセレクタを文字列で指定します。例えば、「.my-class」を指定すれば「my-classというクラスを持つ要素」であるか、「#my-id」を指定すれば「my-idというIDを持つ要素」であるか、あるいは「div.active」と指定すれば「activeクラスを持つdiv要素」であるかといった条件を検査できます。
メソッドの実行結果として、指定されたCSSセレクタが要素に一致する場合はブール値のtrueを返し、一致しない場合はfalseを返します。この機能は、WebブラウザのJavaScriptで提供されるElement.matches()メソッドと同様の働きをします。
システムエンジニアを目指す初心者の方にとって、このメソッドはWebページ上の特定の要素が、ある条件を満たしているかを手軽に確認できる強力なツールとなります。例えば、ユーザーがクリックした要素が特定のカテゴリを示すクラスを持っているかを調べたり、フォームの入力要素が特定の状態にあるかを判断したりする場面で役立ちます。複雑なDOMツリー構造の中から目的の要素をフィルタリングしたり、イベントハンドラで条件に応じた処理を分岐させたりする際に、コードを簡潔かつ効率的に記述するために非常に有用です。
構文(syntax)
1<?php 2 3$document = new Dom\HTMLDocument(); 4$element = $document->createElement('div'); 5$element->setAttribute('class', 'example-class'); 6 7$isMatched = $element->matches('.example-class'); 8 9?>
引数(parameters)
string $selectors
- string $selectors: マッチさせるCSSセレクターを指定する文字列
戻り値(return)
bool
指定されたDOM要素が、指定されたCSSセレクタに一致するかどうかを示す真偽値を返します。一致する場合はtrue、一致しない場合はfalseを返します。
サンプルコード
PHP 8 Dom\HTMLElement matchesセレクタ判定する
1<?php 2 3// PHP 8 で導入された Dom\HTMLElement クラスの matches メソッドのサンプルコードです。 4// このメソッドは、特定のHTML要素が指定されたCSSセレクタにマッチするかどうかを判定するために使用されます。 5 6use Dom\Document; 7use Dom\HTMLElement; 8 9/** 10 * 指定されたHTML文字列から要素を抽出し、その要素がCSSセレクタにマッチするかどうかを判定します。 11 * システムエンジニアを目指す初心者にも理解しやすいように、Dom\HTMLElement::matches の基本的な使い方を示します。 12 * 13 * @param string $html HTMLの文字列全体 14 * @param string $elementId テスト対象のHTML要素のID 15 * @param string $selector テストに使用するCSSセレクタ文字列 16 * @return void 結果をコンソールに出力します。 17 */ 18function checkElementMatchesSelector(string $html, string $elementId, string $selector): void 19{ 20 // 1. Dom\Document クラスのインスタンスを作成します。 21 // これはHTMLドキュメント全体を表現します。 22 $document = new Document(); 23 24 // 2. HTML文字列をドキュメントにロードします。 25 // これにより、HTMLの構造が解析され、要素にアクセスできるようになります。 26 $document->loadHtml($html); 27 28 // 3. 指定されたIDを持つHTML要素を取得します。 29 // getElementById は Dom\HTMLElement または null を返します。 30 $element = $document->getElementById($elementId); 31 32 // 要素が正常に取得できたかを確認します。 33 if ($element instanceof HTMLElement) { 34 echo "要素 ID: '{$elementId}' が見つかりました。\n"; 35 echo " テストセレクタ: '{$selector}'\n"; 36 37 // 4. Dom\HTMLElement::matches メソッドを使用して、 38 // 取得した要素が指定されたCSSセレクタにマッチするかどうかを判定します。 39 // 結果は true (マッチする) または false (マッチしない) です。 40 if ($element->matches($selector)) { 41 echo " 結果: 要素はセレクタにマッチします。\n"; 42 } else { 43 echo " 結果: 要素はセレクタにマッチしません。\n"; 44 } 45 } else { 46 // 指定されたIDの要素が見つからなかった場合の処理 47 echo "エラー: ID '{$elementId}' の要素が見つかりませんでした。\n"; 48 } 49 echo "----------------------------------------\n\n"; 50} 51 52// サンプルで使用するHTML文字列を定義します。 53$sampleHtml = <<<HTML 54<!DOCTYPE html> 55<html> 56<head> 57 <title>matches() Method Example</title> 58</head> 59<body> 60 <div id="main-container" class="container app-root"> 61 <p id="intro-paragraph" class="text-content primary"> 62 これは紹介文の段落です。 63 <a href="#" class="link important">詳細はこちら</a> 64 </p> 65 <span id="status-message" class="message hidden"> 66 ステータスメッセージ。 67 </span> 68 <button id="submit-button" class="btn primary"></button> 69 </div> 70</body> 71</html> 72HTML; 73 74// Dom\HTMLElement::matches メソッドの使用例をいくつか示します。 75 76// 例1: IDと単一クラスでのマッチング 77// 'intro-paragraph' というIDを持ち、かつ 'text-content' クラスを持つPタグにマッチするか? 78checkElementMatchesSelector( 79 $sampleHtml, 80 "intro-paragraph", 81 "p#intro-paragraph.text-content" 82); 83 84// 例2: 複数クラスでのマッチング 85// 'main-container' というIDを持ち、かつ 'container' と 'app-root' の両方のクラスを持つDIVタグにマッチするか? 86checkElementMatchesSelector( 87 $sampleHtml, 88 "main-container", 89 "div.container.app-root" 90); 91 92// 例3: 属性セレクタでのマッチング (マッチしない例) 93// 'submit-button' というIDを持つBUTTONタグが、'type="submit"' 属性を持つか? 94// (現在のHTMLでは 'type' 属性がないため、マッチしません) 95checkElementMatchesSelector( 96 $sampleHtml, 97 "submit-button", 98 "button#submit-button[type='submit']" 99); 100 101// 例4: マッチしないケース (存在しないクラス) 102// 'intro-paragraph' というIDを持つ要素が、存在しない 'non-existent-class' クラスを持つか? 103checkElementMatchesSelector( 104 $sampleHtml, 105 "intro-paragraph", 106 ".non-existent-class" 107); 108 109// 例5: マッチしないケース (異なるタグ名) 110// 'status-message' というIDを持つ要素が、DIVタグであるか? (実際はSPANタグなのでマッチしません) 111checkElementMatchesSelector( 112 $sampleHtml, 113 "status-message", 114 "div#status-message" 115);
PHP 8で導入されたDom\HTMLElementクラスのmatchesメソッドは、特定のHTML要素が指定されたCSSセレクタに合致するかどうかを判定するために使用されます。このメソッドは引数としてstring $selectorsを受け取ります。これは、対象の要素がマッチするかをテストするためのCSSセレクタ文字列です。メソッドの戻り値はbool型で、要素がセレクタにマッチすればtrueを、マッチしなければfalseを返します。
サンプルコードでは、まずDom\Documentクラスを用いてHTML文字列を解析し、特定のIDを持つHTMLElementを取得する一連の流れを示しています。要素が正常に取得できたことを確認した後、$element->matches($selector)のようにして、取得したHTML要素が引数で渡されたCSSセレクタにマッチするかどうかを判定しています。たとえば、p#intro-paragraph.text-contentといったセレクタは「IDがintro-paragraphで、かつtext-contentクラスを持つPタグ」に要素が該当するかを調べます。コードの各実行例では、IDやクラス、属性セレクタなど、様々なCSSセレクタを試すことで、matchesメソッドがどのような条件下でtrueまたはfalseを返すかを具体的に示しています。これにより、プログラム内でHTML要素の構造や属性に基づいて条件分岐を行う際の強力なツールとして活用できます。
本サンプルコードで利用しているDom\HTMLElement::matchesメソッドは、PHPのDOM拡張機能が有効であることを前提としています。このメソッドは、対象のHTML要素が、引数で指定されたCSSセレクタ文字列に合致するかを真偽値で返します。安全に利用するためには、Dom\Document::getElementByIdなどで要素を取得した後、nullでないか、そしてDom\HTMLElementのインスタンスであるかを必ず確認してください。CSSセレクタの記述ミスは、意図しないマッチング結果に繋がりますので、有効なセレクタ文字列を使用することが重要です。この機能は、HTMLの特定の構造を検証したり、要素の条件判定を行ったりする際に非常に有用です。
PHP Dom\HTMLElement::matches でCSSセレクター判定する
1<?php 2 3/** 4 * Dom\HTMLElement::matches メソッドの使用例。 5 * このメソッドは、要素が特定のCSSセレクター文字列に一致するかどうかを判定します。 6 * キーワードの「regex」についてですが、Dom\HTMLElement::matches はCSSセレクターを扱います。 7 * CSSセレクターは要素をパターンマッチングするメカニズムですが、正規表現とは異なる独自の構文を持ちます。 8 */ 9 10// サンプルHTMLコンテンツを準備 11$htmlContent = <<<HTML 12<!DOCTYPE html> 13<html> 14<head> 15 <title>PHP Dom\HTMLElement::matches Example</title> 16</head> 17<body> 18 <div id="app" class="container main-section"> 19 <h1 class="title">Welcome</h1> 20 <p class="description">これは説明文です。</p> 21 <ul id="menu"> 22 <li class="item active">Home</li> 23 <li class="item">About</li> 24 <li class="item">Contact</li> 25 </ul> 26 </div> 27 <div class="footer"> 28 <p>Copyright 2023</p> 29 </div> 30</body> 31</html> 32HTML; 33 34// DOMDocumentオブジェクトをインスタンス化 35$dom = new DOMDocument(); 36 37// HTMLコンテンツをロード 38// HTML5のタグなどで警告が出ないよう、エラー抑制演算子を使用 39@$dom->loadHTML($htmlContent); 40 41// IDが "app" の要素を取得 42// PHP 8以降ではDOMElementはDom\HTMLElementを継承しているため、matchesメソッドが直接利用可能 43$appElement = $dom->getElementById('app'); 44 45if ($appElement instanceof Dom\HTMLElement) { 46 echo "ID 'app' を持つ要素が見つかりました。\n\n"; 47 48 // 1. 基本的なIDセレクターでのマッチング 49 $selector1 = '#app'; 50 if ($appElement->matches($selector1)) { 51 echo "要素はセレクター '{$selector1}' にマッチします。\n"; // この要素自身が #app なのでtrue 52 } else { 53 echo "要素はセレクター '{$selector1}' にマッチしません。\n"; 54 } 55 56 // 2. クラスセレクターでのマッチング 57 $selector2 = '.main-section'; 58 if ($appElement->matches($selector2)) { 59 echo "要素はセレクター '{$selector2}' にマッチします。\n"; // この要素に .main-section クラスがあるのでtrue 60 } else { 61 echo "要素はセレクター '{$selector2}' にマッチしません。\n"; 62 } 63 64 // 3. 複数のクラスセレクターでのマッチング 65 $selector3 = '.container.main-section'; 66 if ($appElement->matches($selector3)) { 67 echo "要素はセレクター '{$selector3}' にマッチします。\n"; // 両方のクラスを持つのでtrue 68 } else { 69 echo "要素はセレクター '{$selector3}' にマッチしません。\n"; 70 } 71 72 // 4. 複数セレクター(OR条件)でのマッチング 73 $selector4 = '.wrong-class, #app'; 74 if ($appElement->matches($selector4)) { 75 echo "要素はセレクター '{$selector4}' にマッチします。\n"; // #app にマッチするのでtrue 76 } else { 77 echo "要素はセレクター '{$selector4}' にマッチしません。\n"; 78 } 79 80 // 5. マッチしないセレクターの例 81 // matchesメソッドは要素自身がセレクターにマッチするかを判定するため、子孫セレクターは機能しない 82 $selector5 = 'div p'; // これは "divの中のp要素" を意味するが、$appElement自体はp要素ではない 83 if ($appElement->matches($selector5)) { 84 echo "要素はセレクター '{$selector5}' にマッチします。\n"; 85 } else { 86 echo "要素はセレクター '{$selector5}' にマッチしません。\n"; // falseとなる 87 } 88 89 // 6. 属性セレクターでのマッチング (例: class属性が'container'を含むかどうか) 90 $selector6 = '[class~="container"]'; 91 if ($appElement->matches($selector6)) { 92 echo "要素はセレクター '{$selector6}' にマッチします。\n"; // class属性に 'container' が含まれるのでtrue 93 } else { 94 echo "要素はセレクター '{$selector6}' にマッチしません。\n"; 95 } 96 97 echo "\n"; 98 99 // 別の要素で matches メソッドを試す 100 $listItem = $dom->querySelector('#menu .item.active'); // querySelector は Dom\HTMLElement::querySelector を使用 101 if ($listItem instanceof Dom\HTMLElement) { 102 echo "アクティブなリストアイテムが見つかりました。\n"; 103 $itemSelector = 'li.item.active'; 104 if ($listItem->matches($itemSelector)) { 105 echo "リストアイテムはセレクター '{$itemSelector}' にマッチします。\n"; 106 } else { 107 echo "リストアイテムはセレクター '{$itemSelector}' にマッチしません。\n"; 108 } 109 110 $wrongSelector = 'li.item:first-child'; // これは最初のli要素だが、matchesは自分自身がマッチするかを判定 111 if ($listItem->matches($wrongSelector)) { 112 echo "リストアイテムはセレクター '{$wrongSelector}' にマッチします。\n"; 113 } else { 114 echo "リストアイテムはセレクター '{$wrongSelector}' にマッチしません。\n"; // falseとなる(実際は2番目のliなので) 115 } 116 } else { 117 echo "アクティブなリストアイテムが見つかりませんでした。\n"; 118 } 119 120} else { 121 echo "ID 'app' を持つ要素が見つかりませんでした。HTMLの構造を確認してください。\n"; 122} 123 124?>
Dom\HTMLElement::matchesメソッドは、特定のDOM要素が指定されたCSSセレクターの条件に合致するかどうかを判定するために使用されます。このメソッドは、引数としてCSSセレクターの文字列を受け取ります。そして、呼び出し元の要素がそのセレクターに一致すればtrueを、一致しなければfalseを真偽値として返します。
ここでキーワードにある「regex(正規表現)」についてですが、matchesメソッドが扱うのはCSSセレクターであり、正規表現とは異なる独自の構文でHTML要素をパターンマッチングするメカニズムです。CSSセレクターは、ID(#id)、クラス(.class)、要素名、属性などを用いてウェブページの要素を特定する際に利用されます。
サンプルコードでは、まずHTMLコンテンツをロードしてDOMオブジェクトを生成し、そこから特定の要素(例えばIDが"app"のdiv要素)を取得しています。取得した$appElementに対して、IDセレクターやクラスセレクター、複数の条件を組み合わせたセレクター、あるいは属性セレクターなど、様々なCSSセレクターをmatchesメソッドに渡して、その要素がセレクターに一致するかどうかを確認しています。
特に重要な点として、matchesメソッドは「その要素自身」がセレクターの条件を満たすかを判定します。例えば、div pのような子孫セレクターは、「div要素の中にあるp要素」を意味しますが、div要素自身にmatches('div p')を実行してもp要素ではないためfalseとなります。これは、要素が子孫を持つかどうかではなく、その要素自身がセレクターに合致するかを見るためです。このメソッドは、ウェブページの特定の要素が意図した条件を満たしているかを効率的にチェックしたい場合に役立ちます。
Dom\HTMLElement::matchesメソッドは、要素がCSSセレクターに一致するかを判定します。初心者が間違いやすい点として、引数に指定するのは正規表現ではなく、CSSセレクターの構文であることに注意してください。このメソッドは、呼び出し元の「要素自身」がセレクターにマッチするかを判定します。そのため、「子孫セレクター(例: div p)」のように、その要素の子孫や兄弟を対象とするセレクターは期待通りに機能しない場合があります。
サンプルコードでは、DOMDocument::loadHTMLにエラー抑制演算子@を使用していますが、これは不正なHTMLマークアップやHTML5タグ利用時に発生する警告メッセージを抑制するためです。実運用ではエラーハンドリングを適切に行うことを検討してください。取得した要素がDom\HTMLElement型であることをinstanceofで確認し、安全にメソッドを呼び出すようにしてください。PHP 8以降ではDOMElementがDom\HTMLElementを継承しているため、matchesメソッドを直接利用できます。