【PHP8.x】textContentプロパティの使い方

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

作成日: 更新日:

基本的な使い方

textContentプロパティは、DOMDocumentオブジェクトのテキストコンテンツ全体を取得または設定するために使用されるプロパティです。このプロパティは、ドキュメント内のすべてのテキストノードを連結した文字列を返します。

取得時には、ドキュメント内のテキストノードを探索し、それらのテキストノードの値を連結して返します。これにより、HTMLドキュメントやXMLドキュメントから、要素のタグを除いたテキスト部分のみを効率的に抽出することができます。空白文字や改行もテキストノードの一部として含まれるため、必要に応じてトリミングや置換などの処理を行うことが推奨されます。

設定時には、ドキュメント内の既存の子ノードをすべて削除し、指定されたテキストコンテンツを持つ新しいテキストノードをドキュメントのルートノードの子ノードとして追加します。この操作によって、ドキュメントの内容が完全に置き換えられるため、注意が必要です。例えば、HTMLドキュメントにテキストを設定すると、<p>タグなどの構造は失われ、設定されたテキストのみが残ります。

textContentプロパティは、DOMDocumentオブジェクトが表すドキュメント全体のテキストコンテンツを操作するための便利な手段を提供します。ドキュメントからテキスト情報を抽出したり、ドキュメントの内容をテキストで置き換えたりする際に活用できます。ただし、ドキュメントの構造を維持する必要がある場合は、他のDOM操作メソッドと組み合わせて使用するなど、適切な処理を検討する必要があります。

構文(syntax)

1DOMDocument::$textContent;

引数(parameters)

引数なし

引数はありません

戻り値(return)

string

DOMDocumentオブジェクトが表すノードとそのすべての子孫ノードのテキストコンテンツを結合した文字列を返します。

サンプルコード

PHP DOMDocument textContent でテキスト取得

1<?php
2
3/**
4 * HTML文字列からDOMDocumentを作成し、特定の要素のtextContentプロパティを取得するサンプル。
5 *
6 * DOMDocument::textContent は、ノードとその子孫のテキストコンテンツを返します。
7 * HTMLタグやコメントは含まれず、純粋なテキストのみが抽出されます。
8 *
9 * @param string $htmlString 処理するHTML文字列。
10 * @return void
11 */
12function demonstrateDomTextContent(string $htmlString): void
13{
14    // DOMDocumentオブジェクトを新しく作成します。
15    $dom = new DOMDocument();
16
17    // HTMLのパース中に発生する警告やエラーを抑制します。
18    // これにより、不完全なHTMLでもスクリプトが停止することなく処理を続行できます。
19    libxml_use_internal_errors(true);
20    // HTML文字列をDOMDocumentにロードします。
21    $dom->loadHTML($htmlString);
22    // 処理後、内部エラーをクリアします。
23    libxml_clear_errors();
24
25    echo "--- オリジナルHTML ---" . PHP_EOL;
26    echo $htmlString . PHP_EOL;
27    echo "----------------------" . PHP_EOL . PHP_EOL;
28
29    // 1. body要素全体のテキストコンテンツを取得する例
30    // getElementsByTagName()はDOMNodeListを返すため、item(0)で最初の要素を取得します。
31    $body = $dom->getElementsByTagName('body')->item(0);
32
33    if ($body instanceof DOMElement) {
34        // body要素のtextContentプロパティにアクセスし、純粋なテキストを取得します。
35        $bodyTextContent = $body->textContent;
36        echo "body要素全体のテキストコンテンツ:" . PHP_EOL;
37        echo "--------------------------------" . PHP_EOL;
38        echo trim($bodyTextContent) . PHP_EOL . PHP_EOL; // 余分な空白を除去して表示
39    } else {
40        echo "HTMLにbody要素が見つかりませんでした。" . PHP_EOL . PHP_EOL;
41    }
42
43    // 2. 特定のp要素のテキストコンテンツを取得する例
44    $paragraphs = $dom->getElementsByTagName('p');
45
46    if ($paragraphs->length > 0) {
47        // 最初のpタグのtextContentを取得します。
48        $firstParagraph = $paragraphs->item(0);
49        $paragraphTextContent = $firstParagraph->textContent;
50        echo "最初のpタグのテキストコンテンツ:" . PHP_EOL;
51        echo "-------------------------------" . PHP_EOL;
52        echo trim($paragraphTextContent) . PHP_EOL . PHP_EOL; // 余分な空白を除去して表示
53    } else {
54        echo "HTMLにpタグが見つかりませんでした。" . PHP_EOL . PHP_EOL;
55    }
56}
57
58// サンプルとして使用するHTML文字列。
59// ここにはh1、p、div、コメントなどが含まれています。
60// textContentはこれらのタグを無視し、純粋なテキストのみを抽出します。
61$sampleHtml = <<<HTML
62<!DOCTYPE html>
63<html>
64<head>
65    <title>DOMDocument::textContentサンプル</title>
66</head>
67<body>
68    <h1>こんにちは、<b>世界</b>!</h1>
69    <p>これは、<i>PHP</i> の <span>DOMDocument</span> を使った
70    <a href="#">textContent</a> の<strong>例</strong>です。</p>
71    <div>
72        <!-- このコメントはtextContentには含まれません -->
73        <p>子要素のテキスト。</p>
74        さらにテキスト。
75    </div>
76</body>
77</html>
78HTML;
79
80// 関数を実行し、textContentの動作を確認します。
81demonstrateDomTextContent($sampleHtml);
82
83?>

PHPのDOMDocument::textContentは、HTMLやXMLドキュメントの特定のノード(要素)から、タグやコメントを除いた「純粋なテキストコンテンツ」を抽出するためのプロパティです。このプロパティには引数がなく、戻り値として抽出されたテキストを文字列(string)で返します。

textContentの主な機能は、要素とそのすべての子孫要素が持つテキストデータを連結して取得することです。これにより、<h1>こんにちは、<b>世界</b>!</h1>のようなHTML構造からは、「こんにちは、世界!」というテキストのみが得られ、タグは含まれません。

サンプルコードでは、まず与えられたHTML文字列をDOMDocumentオブジェクトに読み込んでいます。この際、libxml_use_internal_errorsを一時的に有効にすることで、不完全なHTMLでもエラーを抑制し、パース処理を続行可能にしています。その後、getElementsByTagNameメソッドを使用してbody要素やp要素といった特定のHTML要素を取得し、それぞれのtextContentプロパティにアクセスしています。こうすることで、各HTML要素内に含まれる余分なHTMLタグを取り除き、純粋なテキスト情報だけを抽出して表示しています。textContentは、WebスクレイピングなどでHTMLからテキスト情報のみを効率的に取得したい場合に非常に便利な機能です。

textContentプロパティは、HTMLタグやコメントなどを完全に除外し、要素内の純粋なテキストコンテンツを文字列として取得します。元のHTMLの改行やインデントによる不要な空白が含まれる場合があるため、サンプルコードのようにtrim()関数で整形すると、よりきれいに表示されます。DOMDocument::loadHTML()でHTMLをパースする際、不完全なHTMLでは警告が発生することがあります。サンプルではlibxml_use_internal_errors(true)で抑制していますが、実際のシステムではエラーを適切に処理する仕組みを検討してください。また、getElementsByTagName()などで要素を取得し、item(0)でアクセスする際には、対象の要素が存在するかどうかを事前に確認することが、エラーを防ぐ上で非常に重要です。

PHP DOM: textContentとnodeValueの違いを理解する

1<?php
2
3/**
4 * DOMNode::textContent と DOMNode::nodeValue の違いを示すサンプルコード
5 *
6 * DOMNode::textContent:
7 *   - ノードとそのすべての子孫ノードのテキストコンテンツを連結して返します。
8 *   - HTMLタグやコメントは取り除かれ、純粋なテキストが抽出されます。
9 *
10 * DOMNode::nodeValue:
11 *   - ノードの種類によって異なる値を返します。
12 *   - 要素ノード(DOMElement)の場合、通常は null を返します。
13 *   - テキストノード(DOMText)の場合、そのテキスト内容を返します。
14 *   - コメントノード(DOMComment)の場合、コメント内容を返します。
15 *   - 属性ノード(DOMAttr)の場合、その属性値を返します。
16 */
17function demonstrateDomNodeProperties(): void
18{
19    // 比較に使用するHTML文字列
20    $htmlString = <<<HTML
21<html>
22<body>
23    <div id="container">
24        <!-- これはコメントノードです -->
25        <p>こんにちは、<b>世界</b>!</p>
26        <span class="sub-text">追加の<em>強調</em>テキスト。</span>
27        純粋なテキストノード。
28    </div>
29    <div id="empty-div"></div>
30</body>
31</html>
32HTML;
33
34    // DOMDocument オブジェクトを生成
35    $dom = new DOMDocument();
36    // HTML文字列をロード
37    // HTMLのパースエラーを抑制し、内部エラーハンドリングを有効にする(より堅牢な方法)
38    libxml_use_internal_errors(true);
39    $dom->loadHTML($htmlString);
40    libxml_clear_errors(); // 処理後、エラーをクリア
41
42    echo "--- DOMNode::textContent と DOMNode::nodeValue の比較 ---\n\n";
43
44    // idが 'container' の要素を取得
45    $containerElement = $dom->getElementById('container');
46
47    if ($containerElement) {
48        echo "■ 要素: <div id=\"container\">...\n";
49        echo "  textContent: '" . $containerElement->textContent . "'\n";
50        echo "  nodeValue:   " . var_export($containerElement->nodeValue, true) . "\n\n"; // 要素ノードなので null
51
52        // idが 'container' 内の p 要素を取得
53        $pElement = $containerElement->getElementsByTagName('p')->item(0);
54        if ($pElement) {
55            echo "■ 要素: <p>...</p>\n";
56            echo "  textContent: '" . $pElement->textContent . "'\n";
57            echo "  nodeValue:   " . var_export($pElement->nodeValue, true) . "\n\n"; // 要素ノードなので null
58
59            // p要素内のテキストノード 'こんにちは、' を取得
60            // (DOMの仕様上、テキストノードも子ノードとして扱われる)
61            $textNodeP = $pElement->firstChild;
62            // 空白文字ノードなどをスキップして、適切なテキストノードを見つける
63            while ($textNodeP && !($textNodeP instanceof DOMText)) {
64                $textNodeP = $textNodeP->nextSibling;
65            }
66
67            if ($textNodeP instanceof DOMText) {
68                echo "■ テキストノード (p要素内): '" . $textNodeP->nodeValue . "'\n";
69                echo "  textContent: '" . $textNodeP->textContent . "'\n"; // テキストノード自身の内容
70                echo "  nodeValue:   '" . $textNodeP->nodeValue . "'\n\n";   // テキストノード自身の内容 (textContentと同じ)
71            }
72        }
73
74        // コメントノードを取得
75        // (DOMツリーを探索してコメントノードを見つける)
76        $commentNode = null;
77        foreach ($containerElement->childNodes as $childNode) {
78            if ($childNode instanceof DOMComment) {
79                $commentNode = $childNode;
80                break;
81            }
82        }
83
84        if ($commentNode) {
85            echo "■ コメントノード: <!-- ... -->\n";
86            echo "  textContent: '" . $commentNode->textContent . "'\n"; // コメントノードの内容
87            echo "  nodeValue:   '" . $commentNode->nodeValue . "'\n\n";   // コメントノードの内容 (textContentと同じ)
88        }
89
90        // '純粋なテキストノード。' を含む DOMText ノードを取得
91        $textNodeAlone = null;
92        foreach ($containerElement->childNodes as $childNode) {
93            if ($childNode instanceof DOMText && trim($childNode->nodeValue) === '純粋なテキストノード。') {
94                $textNodeAlone = $childNode;
95                break;
96            }
97        }
98        if ($textNodeAlone) {
99            echo "■ 単独のテキストノード: '" . trim($textNodeAlone->nodeValue) . "'\n";
100            echo "  textContent: '" . $textNodeAlone->textContent . "'\n";
101            echo "  nodeValue:   '" . $textNodeAlone->nodeValue . "'\n\n";
102        }
103
104    } else {
105        echo "ID 'container' の要素が見つかりませんでした。\n";
106    }
107
108    // 空の要素の比較
109    $emptyDiv = $dom->getElementById('empty-div');
110    if ($emptyDiv) {
111        echo "■ 空の要素: <div id=\"empty-div\"></div>\n";
112        echo "  textContent: '" . $emptyDiv->textContent . "'\n"; // 空文字列
113        echo "  nodeValue:   " . var_export($emptyDiv->nodeValue, true) . "\n\n"; // 要素ノードなので null
114    }
115}
116
117// 関数を実行
118demonstrateDomNodeProperties();
119
120?>

PHP 8のDOMDocumentクラスは、HTMLやXML文書を扱うための拡張機能です。その中のtextContentプロパティは、厳密にはDOMNodeクラスに属し、ノードが持つテキストコンテンツを文字列として取得する際に使用します。このプロパティに引数はなく、常に文字列を戻り値として返します。

textContentは、対象のノードとそのすべての子孫ノードに含まれるテキストを連結して取得します。この際、HTMLタグやXMLタグ、コメントなどはすべて取り除かれ、純粋なテキストのみが抽出される点が特徴です。例えば、<p>こんにちは、<b>世界</b>!</p>のようなHTML要素に対してtextContentを使用すると、「こんにちは、世界!」という文字列が得られます。

一方、DOMNode::nodeValueもノードの値を取得するプロパティですが、その挙動はノードの種類によって異なります。要素ノード(例: <div>, <p>)に対してnodeValueを使用すると、通常はnullを返します。しかし、テキストノードやコメントノードに対しては、その内容を文字列として返します。サンプルコードでは、<div id="container">のような要素ノードではnodeValuenullであるのに対し、textContentは子孫の全テキストを返していることが確認できます。コメントノードや単独のテキストノードでは、textContentnodeValueが同じ内容を返すことが示されており、それぞれのプロパティの役割の違いが明確に理解できます。textContentは要素内の視覚的なテキスト全体を取得したい場合に、nodeValueは特定のテキストノードやコメントノードの直接的な内容を取得したい場合に適しています。

PHPのDOM操作では、textContentは要素とその全ての子孫ノードの純粋なテキストを結合して取得します。一方nodeValueはノードの種類で返り値が異なり、要素ノードでは通常nullです。要素内のテキスト取得にはtextContentが適切です。HTMLパースエラーはlibxml_use_internal_errors()libxml_clear_errors()で安定処理できます。ノード取得メソッドはnullを返すため、必ず存在チェックを行い、安全にコードを運用しましょう。

関連コンテンツ

関連プログラミング言語