【PHP8.x】Dom\EntityReference::textContentプロパティの使い方
textContentプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『textContentプロパティは、Dom\EntityReferenceノードのテキスト内容を保持するプロパティです。このプロパティは、あるノードとそのすべての子孫ノードが持つテキスト情報を連結した文字列を取得するために使用されます。しかし、Dom\EntityReferenceオブジェクト、つまりXMLやHTMLドキュメントにおけるエンティティ参照(例: &や<)を表すノードの場合、このtextContentプロパティにアクセスすると常にnullが返されるという特徴があります。これは、エンティティ参照ノード自体が直接的なテキストコンテンツを持たず、ドキュメントが解釈される際に他のノード群に置き換えられるプレースホルダーとしての役割を持つためです。したがって、エンティティが展開された後のテキスト全体を取得するには、このエンティティ参照ノードを含んでいる親要素のtextContentプロパティを参照する必要があります。また、このプロパティは読み取り専用であり、値を代入しようとするとエラーが発生しますので注意してください。』
構文(syntax)
1<?php 2 3// エンティティ参照を含むXML文字列を準備 4$xmlString = <<<XML 5<?xml version="1.0" encoding="UTF-8"?> 6<!DOCTYPE root [ 7 <!ENTITY sample "This is the entity text."> 8]> 9<data> 10 <item>&sample;</item> 11</data> 12XML; 13 14// Dom\Documentオブジェクトを作成してXMLを読み込む 15$document = new Dom\Document(); 16$document->loadXML($xmlString); 17 18// エンティティ参照ノード(Dom\EntityReference)を取得 19$entityRef = $document->getElementsByTagName('item')[0]->firstChild; 20 21// Dom\EntityReferenceオブジェクトのtextContentプロパティから値を取得する 22// このプロパティは、エンティティが展開された後のテキスト内容を返す 23$value = $entityRef->textContent; 24 25// 取得したテキストコンテンツを出力する 26echo $value; 27 28?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMエンティティ参照のテキストコンテンツを文字列で返します。要素がテキストコンテンツを持たない場合はnullを返します。
サンプルコード
PHP DOMEntityReference textContentを取得する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * Dom\EntityReferenceのtextContentプロパティの使用例を示します。 7 * 8 * この関数は、プログラムでエンティティ参照ノード (&) を作成し、 9 * そのtextContentプロパティがエンティティの置換テキスト ('&') を 10 * どのように返すかを確認します。 11 */ 12function demonstrateEntityReferenceTextContent(): void 13{ 14 // 1. DOMDocumentオブジェクトをインスタンス化します。 15 // PHP 8では、多くのDOMクラスが `Dom` 名前空間に属しますが、 16 // 従来のグローバルなクラス名もエイリアスとして利用可能です。 17 $dom = new \DOMDocument('1.0', 'UTF-8'); 18 19 // 2. ルート要素を作成し、ドキュメントに追加します。 20 $root = $dom->createElement('message'); 21 $dom->appendChild($root); 22 23 // 3. '&' (ampersand) を表すエンティティ参照ノードを作成します。 24 // このノードのクラスは Dom\EntityReference (またはエイリアスの DOMEntityReference) です。 25 $entityNode = $dom->createEntityReference('amp'); 26 $root->appendChild($entityNode); 27 28 // 4. Dom\EntityReference ノードの textContent プロパティを取得します。 29 // '&' というエンティティ参照のテキストコンテンツは、 30 // それが表す文字である '&' になります。 31 // 戻り値は string|null ですが、この場合は string '&' が返ります。 32 $textContent = $entityNode->textContent; 33 34 // 5. 取得したtextContentを出力します。 35 // 期待される出力: The textContent of the '&' entity reference is: & 36 echo "The textContent of the '&' entity reference is: " . $textContent . PHP_EOL; 37} 38 39// 関数を実行して結果を表示します。 40demonstrateEntityReferenceTextContent(); 41 42?>
このPHPサンプルコードは、XMLやHTMLの文書内で特殊文字を表す「エンティティ参照」から、それが示す実際のテキスト内容を取得する方法を解説しています。ここで中心となるのが、Dom\EntityReferenceオブジェクトのtextContentプロパティです。
コードでは、まずDOMDocumentを使い、createEntityReference('amp')という命令で「&」という文字を表すためのエンティティ参照ノード(&)を作成しています。エンティティ参照とは、このように特定の記号を安全に文書内に記述するための仕組みです。
次に、作成したエンティティ参照ノードのtextContentプロパティにアクセスしています。このプロパティは引数を取らず、そのエンティティ参照が本来表現しているテキストを文字列(string)として返します。もしテキスト内容が存在しない場合はnullを返します。この例では、「&」が表す文字は「&」であるため、文字列'&'が取得できます。
最終的に、取得した「&」という文字を出力することで、textContentプロパティがエンティティ参照の見た目ではなく、その実体となるテキストを返すことを確認できます。
textContentプロパティは、&のようなHTMLエンティティ参照そのものではなく、それが示す実際の文字、この場合は&を返します。このプロパティは読み取り専用であり、値を代入しようとするとエラーになるため注意してください。戻り値はstringまたはnullとなりうるため、実際の開発では値がnullでないことを確認してから利用するのが安全です。また、取得した値をWebページに出力する際は特に注意が必要です。textContentはテキストをデコードするため、そのまま出力すると意図しないHTMLタグが実行されるクロスサイトスクリプティング(XSS)脆弱性につながる可能性があります。安全のため、htmlspecialchars()関数などを使って必ずエスケープ処理を行ってください。
textContentとnodeValueの違いを比較する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOM要素における textContent と nodeValue の違いを比較します。 7 * 8 * `textContent` は要素とそのすべての子孫のテキスト内容を連結して取得します。 9 * `nodeValue` は要素ノード (DOMElement) 自体には適用されず、常にnullを返します。 10 * 主にテキストノードやコメントノードの値を取得するために使用されます。 11 */ 12function compareNodeValueAndTextContent(): void 13{ 14 // 比較対象となるHTML文字列 15 $html = '<div id="container">これは <span>子要素のテキスト</span> です。<!-- コメント --></div>'; 16 17 // DOMDocumentオブジェクトを生成し、HTMLを読み込む 18 $dom = new DOMDocument(); 19 // HTML5のタグを正しく解釈し、不要な警告を抑制するために@を使用 20 @$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 21 22 // id="container" のdiv要素を取得 23 $element = $dom->getElementById('container'); 24 25 if ($element === null) { 26 echo '指定された要素が見つかりませんでした。'; 27 return; 28 } 29 30 // --- textContent プロパティの出力 --- 31 // div要素とその子孫(span)のテキストをすべて連結して取得します。 32 // HTMLタグやコメントは自動的に取り除かれます。 33 echo '--- $element->textContent ---' . PHP_EOL; 34 echo '結果: ' . $element->textContent . PHP_EOL; 35 // 期待される出力: これは 子要素のテキスト です。 36 echo PHP_EOL; 37 38 // --- nodeValue プロパティの出力 --- 39 // 要素ノード (DOMElement) の nodeValue は常に null です。 40 echo '--- $element->nodeValue ---' . PHP_EOL; 41 echo '結果: '; 42 var_dump($element->nodeValue); 43 // 期待される出力: NULL 44 echo PHP_EOL; 45 46 // --- 参考: テキストノードでの nodeValue の使用 --- 47 // div要素の最初の子ノードは「これは 」というテキストノードです。 48 // このテキストノードの nodeValue を取得します。 49 $textNode = $element->firstChild; 50 echo '--- $element->firstChild->nodeValue (テキストノードの値) ---' . PHP_EOL; 51 echo '結果: ' . $textNode->nodeValue . PHP_EOL; 52 // 期待される出力: これは 53} 54 55// 関数を実行 56compareNodeValueAndTextContent();
textContent プロパティは、指定したHTML要素と、その内部に含まれるすべての子孫要素のテキスト内容を連結して、一つの文字列として取得します。このプロパティは値を取得するためのもので、引数は必要ありません。
サンプルコードでは、<div>要素に対して textContent を使用しています。これにより、<div>内のテキスト「これは 」「 です。」と、子要素である<span>のテキスト「子要素のテキスト」が結合され、「これは 子要素のテキスト です。」という文字列が得られます。この過程で、<span>などのHTMLタグやHTMLコメントは自動的に除去されます。
一方、よく似た nodeValue プロパティは、<div>のような要素ノードに対して使用すると常にnullを返します。nodeValueは、要素内のテキスト部分(テキストノード)やコメントなど、個別のノードが持つ値そのものを取得する場合に利用されるものです。
このように、textContent は、Webページに表示されているテキスト全体をタグなどを除いてまとめて取得したい場合に非常に便利な機能です。戻り値は取得したテキスト文字列(string)ですが、対象ノードの種類によってはnullになる場合があります。
textContentは、指定したHTML要素とその内部にある全ての子孫要素のテキストを連結して取得します。HTMLタグやコメントは自動的に取り除かれるため、画面に表示されるテキスト全体を一度に得たい場合に便利です。一方、nodeValueは要素ノード(<div>など)に対して使用すると常にnullを返す点に注意が必要です。こちらは主にテキストノードやコメントノードなど、ノード自体が持つ固有の値を取得するために使います。例えば、要素内の最初のテキスト部分だけを取り出したい場合などに有効です。getElementByIdなどで要素を取得する際は、対象が見つからずnullが返る可能性を考慮し、必ず存在チェックを行ってからプロパティにアクセスすることが安全なコードの基本です。