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

【PHP8.x】Dom\Text::firstChildプロパティの使い方

firstChildプロパティの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

firstChildプロパティは、DOMTextノード(テキストノード)における最初の子ノードを保持するプロパティです。PHPのDOM拡張において、DOMTextオブジェクトが保持するテキストノードが持つ子ノードの中で、一番最初に現れるノードを取得するために使用されます。

DOM(Document Object Model)は、HTMLやXMLドキュメントをプログラムから操作するためのインターフェースです。DOMTextは、DOMにおけるテキストノードを表すクラスで、テキストコンテンツを操作する際に利用されます。

通常、DOMTextノードはテキストデータのみを保持するため、子ノードを持つことは稀です。しかし、DOM構造が複雑な場合や、特殊なケースにおいては、DOMTextノードが子ノードを持つ可能性も考えられます。そのような場合に、firstChildプロパティを使用することで、最初の子ノードにアクセスできます。

firstChildプロパティは、取得のみ可能な読み取り専用のプロパティです。このプロパティに値を設定することはできません。もし、最初の子ノードが存在しない場合(DOMTextノードが子ノードを持たない場合)、firstChildプロパティはnullを返します。

このプロパティを使用することで、DOMツリー構造を辿りながら、特定のテキストノードの子ノードを効率的に操作することができます。例えば、テキストノードに含まれる特定の子要素を検索したり、その属性を変更したりする処理を実装する際に役立ちます。システムエンジニアとしては、DOM構造を理解し、firstChildプロパティのようなAPIを適切に利用することで、効率的なドキュメント操作を実現できます。

構文(syntax)

1readonly public ?Dom\Node $firstChild;

引数(parameters)

引数なし

引数はありません

戻り値(return)

DOMNode|null

Dom\Text クラスの firstChild プロパティは、このテキストノードの最初の子ノードを表す DOMNode オブジェクト、または子ノードが存在しない場合は null を返します。

サンプルコード

PHP Dom\Text firstChild 動作確認

1<?php
2
3/**
4 * Dom\Text::firstChild プロパティの動作を実演する関数。
5 *
6 * この関数は、DOMDocument を使用してHTMLコンテンツをパースし、
7 * Dom\Text ノードと Dom\Element ノードそれぞれの firstChild プロパティが
8 * どのような値を返すかを示します。
9 * Dom\Text ノードはテキストデータそのものであるため、子ノードを持つことはなく、
10 * その firstChild プロパティは常に null を返します。
11 * 一方、Dom\Element ノードは子ノードを持つことができ、その firstChild プロパティは
12 * 最初の子ノード (要素ノードまたはテキストノード) を返します。
13 */
14function demonstrateDomTextFirstChildProperty(): void
15{
16    // DOMDocumentを初期化し、簡単なHTMLコンテンツを読み込む
17    $doc = new DOMDocument();
18    // HTMLコンテンツには要素ノードとテキストノードが含まれる
19    $doc->loadHTML('<div>Hello <b>world</b>!</div>');
20
21    // <div>要素を取得
22    // HTMLの空白を考慮し、正確に要素を取得するため getElementsByTagName を使用
23    $divElement = $doc->getElementsByTagName('div')->item(0);
24
25    if ($divElement instanceof Dom\Element) {
26        echo "--- 親要素 (<div>) の情報 ---\n";
27        echo "ノード名: " . $divElement->nodeName . "\n";
28        echo "ノードタイプ: " . $divElement->nodeType . " (ELEMENT_NODE)\n";
29        echo "ノード値 (子孫テキスト全体): '" . $divElement->nodeValue . "'\n\n";
30        
31        // <div>要素の最初の子ノードを取得
32        // このHTML構造では、テキストノード "Hello " が最初の子になる
33        $firstNodeOfDiv = $divElement->firstChild;
34
35        echo "--- <div>の firstChild (Dom\\Text ノード) の確認 ---\n";
36        if ($firstNodeOfDiv instanceof Dom\Text) {
37            echo "取得したノードは Dom\\Text です。\n";
38            echo "ノード名: " . $firstNodeOfDiv->nodeName . "\n";
39            echo "ノードタイプ: " . $firstNodeOfDiv->nodeType . " (TEXT_NODE)\n";
40            echo "ノード値: '" . $firstNodeOfDiv->nodeValue . "'\n";
41            
42            // Dom\Text ノードはテキストデータであり、内部に子ノードを持つことはできない
43            if ($firstNodeOfDiv->firstChild === null) {
44                echo "-> この Dom\\Text ノードの 'firstChild' は null です。\n";
45                echo "   (テキストノードは子を持てません。)\n\n";
46            } else {
47                echo "-> この Dom\\Text ノードの 'firstChild' は null ではありません (想定外の挙動です)。\n\n";
48            }
49        } else {
50            echo "<div>の最初の子ノードは Dom\\Text ではありませんでした。\n\n";
51        }
52
53        // 一般的な Dom\Element ノードにおける firstChild の使用例も示す
54        // <b>要素を取得
55        $bElement = $divElement->getElementsByTagName('b')->item(0);
56        if ($bElement instanceof Dom\Element) {
57            echo "--- <b>要素 (Dom\\Element ノード) の firstChild の確認 ---\n";
58            echo "取得したノードは Dom\\Element (<b>) です。\n";
59            echo "ノード名: " . $bElement->nodeName . "\n";
60            echo "ノードタイプ: " . $bElement->nodeType . " (ELEMENT_NODE)\n";
61            echo "ノード値: '" . $bElement->nodeValue . "'\n";
62            
63            // <b>要素の最初の子ノードを取得 (テキストノード "world" になる)
64            $firstNodeOfB = $bElement->firstChild;
65            if ($firstNodeOfB instanceof Dom\Text) {
66                echo "-> <b>要素の 'firstChild' は Dom\\Text です。\n";
67                echo "   ノード値: '" . $firstNodeOfB->nodeValue . "'\n";
68                // このテキストノードの firstChild もやはり null
69                if ($firstNodeOfB->firstChild === null) {
70                    echo "   (この Dom\\Text ノードの 'firstChild' も null です。)\n";
71                }
72            } else {
73                echo "-> <b>要素の 'firstChild' は Dom\\Text ではありませんでした。\n";
74            }
75        } else {
76            echo "<b>要素が見つかりませんでした。\n";
77        }
78    } else {
79        echo "<div>要素が見つかりません。\n";
80    }
81}
82
83// 関数を実行して動作を確認
84demonstrateDomTextFirstChildProperty();

このサンプルコードは、PHPのDom\TextクラスのfirstChildプロパティの動作を解説するものです。Dom\Textはテキストノードを表し、HTMLドキュメント内のテキストデータそのものです。firstChildプロパティは、そのノードの最初の子ノードを返しますが、テキストノードは子ノードを持つことができないため、常にnullを返します。

サンプルコードでは、まずDOMDocumentを使用して簡単なHTMLを読み込みます。そして、<div>要素と<b>要素を取得し、それぞれのfirstChildプロパティを調べます。<div>要素の最初の子ノードはテキストノード("Hello ")です。このテキストノードのfirstChildプロパティにアクセスすると、nullが返されることを確認できます。一方、<b>要素のfirstChildプロパティは、テキストノード("world")を返します。こちらも同様に、テキストノードのfirstChildnullです。このように、Dom\TextノードのfirstChildプロパティは常にnullを返すことがわかります。

Dom\TextfirstChildは、テキストノードが子ノードを持たないため、常にnullを返す点に注意が必要です。サンプルコードでは、loadHTMLでHTMLを読み込む際、空白もテキストノードとして扱われるため、firstChildが予期せぬテキストノードを指すことがあります。getElementsByTagNameで要素を取得する際、item(0)で確実に最初の要素を取得しているか確認しましょう。instanceofを使って型をチェックすることで、予期せぬエラーを防ぎ、コードの安全性を高めることができます。また、nodeValueは要素ノードの場合、子孫のテキスト全体を返す点も覚えておきましょう。

PHP DOM Text firstChild を確認する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * Dom\TextのfirstChildプロパティの動作を示すサンプルコード。
7 *
8 * `Dom\Text`ノードは純粋なテキストデータを表し、子ノードを持つことができません。
9 * そのため、継承された`firstChild`プロパティにアクセスしても、常に`null`が返されます。
10 * このコードは、その動作を具体的に確認します。
11 */
12function demonstrateDomTextFirstChild(): void
13{
14    // 1. DOMDocumentオブジェクトを生成し、HTMLの断片を読み込みます。
15    $dom = new DOMDocument();
16
17    // loadHTMLは通常<html><body>タグを自動補完しますが、
18    // オプションで抑制し、<p>タグのみを解析対象とします。
19    $options = LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD;
20    $dom->loadHTML('<p>Hello World</p>', $options);
21
22    // 2. 最初の<p>要素を取得します。
23    // getElementsByTagNameはリストを返すため、item(0)で最初の要素にアクセスします。
24    $pElement = $dom->getElementsByTagName('p')->item(0);
25
26    // 3. <p>要素の最初の子ノードを取得します。
27    // この場合、"Hello World"というテキストを表す Dom\Text オブジェクトが返されます。
28    $textNode = $pElement->firstChild;
29
30    // 4. 取得したノードが実際にDom\Textのインスタンスであることを確認します。
31    if ($textNode instanceof DOMText) {
32        echo '取得したノードのクラス: ' . get_class($textNode) . PHP_EOL;
33        echo 'テキストノードの値: ' . $textNode->nodeValue . PHP_EOL;
34
35        // 5. Dom\TextオブジェクトのfirstChildプロパティにアクセスします。
36        // テキストノードは子を持てないため、この値は必ず null になります。
37        $firstChild = $textNode->firstChild;
38
39        echo 'テキストノードの firstChild プロパティの値: ';
40        var_dump($firstChild); // 出力は NULL となります。
41    } else {
42        echo 'テキストノードの取得に失敗しました。';
43    }
44}
45
46// 関数を実行して結果を確認します。
47demonstrateDomTextFirstChild();

このPHPコードは、HTMLのテキスト部分を表すDom\TextオブジェクトのfirstChildプロパティの動作を解説します。firstChildプロパティは、あるノードが持つ最初の子ノードを取得するために使用されます。このプロパティは引数を持たず、子ノードが存在すればそのオブジェクト(DOMNode)を、存在しなければnullを返します。

サンプルコードでは、まずDOMDocumentクラスを使って<p>Hello World</p>というHTMLを解析します。次に、<p>要素を取得し、そのfirstChildプロパティを使ってテキスト部分である「Hello World」をDom\Textオブジェクトとして取り出します。

このコードの重要な点は、Dom\Textオブジェクトが純粋なテキストデータを表す「末端」のノードであるという性質です。そのため、テキストノード自体がさらに子ノードを持つことは構造上ありません。したがって、取得したDom\Textオブジェクトに対してfirstChildプロパティで子ノードを取得しようとすると、その結果は常にnullとなります。コードの最後では、var_dump関数を使い、実際にnullが返されることを確認しています。

Dom\Textノードは純粋なテキストデータのみを持ち、子ノードを持つことはできません。したがって、Dom\Textインスタンスに対してfirstChildプロパティにアクセスしても、常にnullが返されることに注意が必要です。これは、DOMNodeクラスから継承されたプロパティですが、Dom\Textの特性上、その値は常にnullとなります。要素ノード(例:<p>タグ)のfirstChildは、テキストノードや他の要素ノードなど実際の子ノードを返しますが、テキストノード自体の子ノードは存在しません。この点を理解することで、DOMツリーの探索や操作時に意図しないnullの扱いを避け、堅牢なコードを記述できます。DOMTextクラスはDOMNodeを継承しており、様々なDOM操作プロパティを持ちますが、その振る舞いは実際のノードタイプによって異なることを認識しておくことが重要です。

関連コンテンツ

関連プログラミング言語