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

【PHP8.x】Dom\HTMLElement::closest()メソッドの使い方

closestメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

closestメソッドは、Dom\HTMLElementクラスに属し、現在のHTML要素からDOMツリーを上方向にたどり、指定されたセレクタに一致する最も近い祖先要素を検索して取得するメソッドです。

このメソッドは、引数としてCSSセレクタ文字列を一つ受け取ります。例えば、.my-classdiv, #my-idのようなセレクタを指定できます。現在の要素から親要素、さらにその親要素へと順に遡りながら、指定されたセレクタに合致する最初の要素を見つけると、その要素をDom\Elementオブジェクトとして返します。もし、DOMツリーのルートに到達しても指定されたセレクタに一致する祖先要素が見つからない場合は、nullを返します。

closestメソッドは、複雑なHTML構造の中で特定の親要素を効率的に見つけ出す際に非常に役立ちます。例えば、あるボタンがクリックされたときに、そのボタンを含む特定のクラス名を持つdiv要素全体に対して何か操作を行いたい場合などに利用できます。イベントが発生した要素から、イベントハンドラを割り当てたい対象の親要素を簡単に見つけ出すことが可能です。これにより、DOMツリー全体を巡回する複雑なロジックを自分で書く手間が省け、コードの可読性と保守性が向上します。PHPでWebページのDOM構造を操作する際に、開発者がより直感的かつ効率的に要素間の関係性を処理できるようサポートします。

構文(syntax)

1<?php
2
3$html = '<div class="ancestor"><p><span class="target"></span></p></div>';
4$document = new Dom\Document();
5$document->loadHTML($html);
6
7// Dom\HTMLElement のインスタンスを取得します
8$targetElement = $document->querySelector('span.target');
9
10// closest メソッドを呼び出し、指定されたセレクタに一致する最も近い祖先要素を検索します
11$closestAncestor = $targetElement->closest('div.ancestor');
12
13?>

引数(parameters)

string $selectors

  • string $selectors: 指定するCSSセレクター文字列

戻り値(return)

?Dom\Element

指定された要素、またはその親要素の中から、条件に一致する最も近い祖先要素を返します。一致する要素が見つからなかった場合は null を返します。

サンプルコード

PHP DOM: closestメソッドで祖先要素を検索

1<?php
2
3namespace App;
4
5use Dom\Document;
6use Dom\HTMLElement;
7use Dom\Element;
8
9/**
10 * HTML構造内で指定された要素の最も近い祖先要素または自身を検索します。
11 *
12 * この関数は、Dom\HTMLElement::closest() メソッドの利用方法をデモンストレーションします。
13 * 指定されたCSSセレクタに一致する最も近い親要素(または自身)を見つけるために使用されます。
14 *
15 * @param string $htmlContent 検索対象となるHTMLコンテンツ。
16 * @param string $targetId 検索を開始する要素のID。
17 * @param string $selector 検索する祖先要素のCSSセレクタ(例: 'div', '.container', 'section#main')。
18 * @return ?Element 指定されたセレクタに一致する最も近い祖先要素または自身、見つからない場合はnull。
19 */
20function findClosestDomElement(string $htmlContent, string $targetId, string $selector): ?Element
21{
22    // 新しいDOMドキュメントを作成します。
23    $document = new Document();
24
25    // HTMLコンテンツをドキュメントに読み込みます。
26    // エラーが発生する可能性があるため、@ を使って警告を抑制していますが、
27    // 実運用では適切なエラーハンドリングが必要です。
28    @$document->loadHTML($htmlContent);
29
30    // 検索を開始する要素をIDで取得します。
31    $targetElement = $document->getElementById($targetId);
32
33    // 対象要素が見つからない、またはHTMLElementでない場合は処理を終了します。
34    if (!$targetElement instanceof HTMLElement) {
35        echo "エラー: 指定されたID '{$targetId}' の要素が見つからないか、HTMLElementではありません。\n";
36        return null;
37    }
38
39    echo "対象要素: <{$targetElement->tagName} id=\"{$targetId}\">\n";
40    echo "検索セレクタ: '{$selector}'\n";
41
42    // Dom\HTMLElement::closest() メソッドを使用して、
43    // 指定されたセレクタに一致する最も近い祖先要素または自身を検索します。
44    // このメソッドは、対象要素から親方向へDOMツリーを遡り、最初に見つかった一致要素を返します。
45    $closestElement = $targetElement->closest($selector);
46
47    if ($closestElement) {
48        echo "見つかった要素: <{$closestElement->tagName}> (クラス: {$closestElement->getAttribute('class')}, ID: {$closestElement->getAttribute('id')})\n";
49    } else {
50        echo "セレクタ '{$selector}' に一致する最も近い要素は見つかりませんでした。\n";
51    }
52
53    return $closestElement;
54}
55
56// --- サンプルコードの実行例 ---
57
58// 簡単なHTML構造を定義します。
59$html = <<<HTML
60<!DOCTYPE html>
61<html>
62<head>
63    <title>PHP closest メソッドサンプル</title>
64</head>
65<body>
66    <div class="wrapper" id="wrapperDiv">
67        <section class="main-section">
68            <article class="card-item">
69                <span id="myTargetSpan" class="data-label">
70                    重要なデータ
71                </span>
72            </article>
73        </section>
74        <p>別のコンテンツ</p>
75    </div>
76    <footer id="footer">フッター</footer>
77</body>
78</html>
79HTML;
80
81echo "--- 実行例 1: 直近の 'article' 要素を検索 ---\n";
82// 'myTargetSpan' の直近の 'article' 祖先要素を検索します。
83$result1 = findClosestDomElement($html, 'myTargetSpan', 'article');
84echo "----------------------------------------\n\n";
85
86echo "--- 実行例 2: クラス名を持つ 'div' 要素を検索 ---\n";
87// 'myTargetSpan' から最も近いクラスが 'wrapper' の 'div' 要素を検索します。
88$result2 = findClosestDomElement($html, 'myTargetSpan', 'div.wrapper');
89echo "----------------------------------------\n\n";
90
91echo "--- 実行例 3: 存在しない祖先要素を検索 ---\n";
92// 'myTargetSpan' の祖先ではない 'footer' 要素を検索します。
93$result3 = findClosestDomElement($html, 'myTargetSpan', 'footer');
94echo "----------------------------------------\n\n";
95
96echo "--- 実行例 4: 自身がセレクタに一致する場合 ---\n";
97// 'myTargetSpan' 自身が 'span' なので、自身が返されます。
98$result4 = findClosestDomElement($html, 'myTargetSpan', 'span');
99echo "----------------------------------------\n\n";
100
101?>

PHPのDom\HTMLElement::closest()メソッドは、HTML要素のDOMツリー内で、自身またはその祖先要素の中から、特定のCSSセレクタに一致する最も近い要素を効率的に検索するための機能です。このメソッドは、指定された要素からDOMツリーを親方向へ遡り、引数であるstring $selectorsに合致する最初の要素を見つけ出し、それをDom\Elementオブジェクトとして返します。もし一致する要素が見つからない場合は、nullを返します。

このサンプルコードでは、まず与えられたHTMLコンテンツをDom\Documentに読み込み、特定のIDを持つ要素(例: myTargetSpan)を起点として取得します。その後、その取得した要素に対してclosest()メソッドを呼び出し、様々なCSSセレクタを使って祖先要素の検索を行っています。例えば、'article'を指定すれば最も近いarticle要素を、'div.wrapper'を指定すればクラス名がwrapperdiv要素を検索します。また、自身がセレクタに一致する場合(例: 'span'myTargetSpanを検索)も、自身が結果として返されることが確認できます。このように、closest()メソッドを使用することで、複雑なHTML構造の中から目的の親要素や自身を簡潔かつ正確に特定することが可能になります。

このサンプルコードは、HTMLのDOMツリー内で指定要素の最も近い祖先要素または自身を、CSSセレクタを用いて検索するDom\HTMLElement::closest()メソッドの利用法です。提示された「php closest number in array」というキーワードとは異なり、DOM要素の検索に特化しています。closest()メソッドは、対象要素自身と、その親方向へDOMツリーを遡り、最初に一致した要素を返します。子要素や兄弟要素は検索対象外ですので注意が必要です。引数には有効なCSSセレクタ文字列を指定してください。サンプルではエラー抑制を使用していますが、実運用ではloadHTMLなどのエラーを適切にハンドリングし、堅牢性を確保することが重要です。この機能はPHPのDOM拡張が有効である必要があります。

PHPで配列から最も近い数を見つける

1<?php
2
3/**
4 * 配列の中から指定された数値に最も近い数値を見つけます。
5 *
6 * この関数は、配列内の各数値とターゲット数値の差を計算し、
7 * その絶対値が最も小さい数値を特定することで、最も近い数値を返します。
8 *
9 * @param array<int|float> $numbers 検索対象となる数値の配列。
10 * @param int|float $target 比較対象となる数値。
11 * @return int|float|null 指定された数値に最も近い数値、または配列が空の場合はnull。
12 */
13function findClosestNumber(array $numbers, int|float $target): int|float|null
14{
15    // 配列が空の場合、最も近い数値を見つけることができないためnullを返します。
16    if (empty($numbers)) {
17        return null;
18    }
19
20    // 最も近い数値と、その数値とターゲットとの差の最小値を保持する変数を初期化します。
21    $closestNumber = null;
22    $minDifference = INF; // 差の初期値として無限大を設定します。
23
24    // 配列の各数値をループ処理します。
25    foreach ($numbers as $number) {
26        // 現在の数値とターゲットとの絶対差を計算します。
27        $difference = abs($target - $number);
28
29        // 現在の差がこれまでの最小差よりも小さい場合、
30        // その数値を最も近い数値として更新します。
31        if ($difference < $minDifference) {
32            $minDifference = $difference;
33            $closestNumber = $number;
34        }
35    }
36
37    // 最終的に見つかった最も近い数値を返します。
38    return $closestNumber;
39}
40
41// --- サンプル使用例 ---
42
43// 整数配列での使用例
44$numbersInt = [10, 25, 30, 42, 55, 60, 78, 85, 90];
45$targetInt = 40;
46$closestInt = findClosestNumber($numbersInt, $targetInt);
47// $closestInt には 42 が格納されます。
48
49// 浮動小数点数配列での使用例
50$numbersFloat = [1.2, 3.5, 7.8, 10.1];
51$targetFloat = 5.0;
52$closestFloat = findClosestNumber($numbersFloat, $targetFloat);
53// $closestFloat には 3.5 が格納されます。
54
55// 空の配列での使用例
56$emptyNumbers = [];
57$closestFromEmpty = findClosestNumber($emptyNumbers, 100);
58// $closestFromEmpty には null が格納されます。
59
60// 注意: 出力条件に合わせ、上記の結果を表示する `echo` などのコードは含んでいません。

このサンプルコードは、PHP言語を使用して、数値の配列の中から特定の数値に最も近い値を見つける方法を提示しています。

ここで定義されているfindClosestNumber関数は、二つの引数を受け取ります。一つ目の$numbersは、整数または浮動小数点数が格納された検索対象の配列です。二つ目の$targetは、配列の中から最も近い値を見つけたい目標となる数値です。

関数内部では、まず入力された配列が空でないかを確認します。もし配列が空であれば、比較対象が存在しないため、戻り値としてnullを返します。配列に数値が含まれる場合、関数は配列の各数値と$targetとの差を計算し、その絶対値が最小となる数値を探し出します。これにより、$targetに最も物理的に近い値が特定されます。

処理が完了すると、この関数は$targetに最も近いと判断された数値を返します。もし配列が空であった場合は、前述の通りnullが返されます。このような機能は、大量のデータの中から特定の基準に合う近似値を探す際など、様々なシステムのロジックで役立つでしょう。

この関数は、空の配列が渡された場合にnullを返すため、利用する際は必ず戻り値がnullでないか確認してください。PHP 8のint|floatというユニオン型ヒントにより、整数と浮動小数点数の両方を柔軟に扱えることが特徴です。最も近い数値が複数存在し、ターゲットからの距離が等しい場合、配列内で最初に見つかった数値が返されることにご留意ください。また、配列の全要素を順番に比較するため、要素数が多いほど処理時間が長くなります。提供されたリファレンス情報のDom\HTMLElement::closestは、HTML要素の検索に関するものであり、本サンプルコードの数値配列検索とは異なる機能である点にもご注意ください。

PHPで数値を最も近い整数に丸める

1<?php
2
3/**
4 * 指定された浮動小数点数を最も近い整数に丸めます。
5 *
6 * PHPの組み込み関数であるround()を使用します。
7 * round()関数はデフォルトで、小数点以下が0.5以上であれば切り上げ、
8 * 0.5未満であれば切り捨てて最も近い整数にします。
9 * ただし、x.5の場合の挙動はPHP_ROUND_HALF_UPモードに基づき、ゼロから遠ざかる方向ではなく、
10 * 値が大きくなる方向に丸められます (例: 3.5 -> 4, -3.5 -> -3)。
11 *
12 * @param float $number 丸めたい数値
13 * @return int 最も近い整数に丸められた値
14 */
15function roundToClosestInteger(float $number): int
16{
17    // round() 関数は、第2引数(精度)を省略するか0を指定した場合、
18    // 最も近い整数に丸めます。
19    // 戻り値はfloat型ですが、intへのキャストで整数値として扱います。
20    return (int) round($number);
21}
22
23// サンプルコードの使用例
24echo "--- 最も近い整数への丸め処理の例 ---" . PHP_EOL;
25echo "3.14 を丸める: " . roundToClosestInteger(3.14) . PHP_EOL;   // 出力: 3
26echo "3.7 を丸める: " . roundToClosestInteger(3.7) . PHP_EOL;     // 出力: 4
27echo "3.5 を丸める: " . roundToClosestInteger(3.5) . PHP_EOL;     // 出力: 4 (0.5は切り上げ)
28echo "3.4 を丸める: " . roundToClosestInteger(3.4) . PHP_EOL;     // 出力: 3
29
30echo "-3.14 を丸める: " . roundToClosestInteger(-3.14) . PHP_EOL; // 出力: -3
31echo "-3.7 を丸める: " . roundToClosestInteger(-3.7) . PHP_EOL;   // 出力: -4
32echo "-3.5 を丸める: " . roundToClosestInteger(-3.5) . PHP_EOL;   // 出力: -3 (-0.5は切り上げ、つまり絶対値が小さくなる方向)
33

このコードは、浮動小数点数を最も近い整数に丸める処理をPHPで実装したものです。roundToClosestInteger関数は、丸めたい数値(float型)を引数として受け取り、最も近い整数(int型)を返します。

関数内部では、PHPの組み込み関数であるround()が使用されています。この関数はデフォルトで、小数点以下が0.5以上の場合には切り上げ、0.5未満の場合には切り捨てて最も近い整数に丸めます。例えば、3.14は3に、3.7は4になります。

特に、数値の小数部分がちょうど0.5の場合(例: 3.5や-3.5)の挙動は重要です。PHP 8のround()関数は、このような値をゼロから遠ざかる方向に丸めます。具体的には、3.5は4に、-3.5は-4に丸められます。

round()関数の戻り値はfloat型ですが、roundToClosestInteger関数では(int)への型キャストを行うことで、戻り値が確実にint型となるようにしています。これにより、丸められた結果が常に整数値として扱われ、正確な数値処理が保証されます。

round()関数はデフォルトで最も近い整数に丸めますが、小数点以下が0.5の場合の挙動には特に注意が必要です。PHP_ROUND_HALF_UPモードにより、例えば3.5は4に、-3.5は-3のように、値が大きくなる方向へ丸められます。特に負の数の丸め方は、直感と異なる場合があるため注意してください。また、round()関数の戻り値は浮動小数点数(float型)のため、確実に整数(int型)として扱いたい場合は、サンプルコードのように明示的に(int)で型変換(キャスト)する必要があります。最も近い整数に丸めるためには、round()関数の第2引数を省略するか、0を指定します。

関連コンテンツ

関連プログラミング言語