【PHP8.x】textContentプロパティの使い方
textContentプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
textContentプロパティは、DOMCharacterDataクラスに属し、ノードのテキストコンテンツを保持するプロパティです。PHPのDOM拡張機能の一部として提供されており、ウェブページやXMLドキュメントの構造をプログラムで操作する際に利用されます。
このプロパティを使用すると、指定されたノード、およびそのすべての子孫ノードに含まれる純粋なテキストデータを、一つの連結された文字列として取得することができます。HTMLやXMLのタグ、コメント、処理命令などはすべて無視され、ユーザーが目にするであろうテキスト部分のみが抽出されます。これにより、要素内の装飾や構造に惑わされることなく、コンテンツそのものにアクセスすることが可能になります。例えば、ウェブページから特定の要素内の文章だけを効率的に抽出したい場合や、XMLデータから特定のノードが持つ純粋な値を取得したい場合などに大変便利です。
また、textContentプロパティには新しい文字列を設定することも可能です。このプロパティに文字列を設定すると、対象ノードの既存の子ノードはすべて削除され、新たに指定した文字列を内容とする単一のテキストノードが作成され、そのノードの子として追加されます。これにより、ノードのテキストコンテンツをシンプルかつ直接的に更新することができます。
DOMCharacterDataクラスは、テキストノード(DOMText)、コメントノード(DOMComment)、CDATAセクションノード(DOMCdataSection)といった、文字データを直接保持するノードの基底クラスです。そのため、textContentプロパティは、これらの種類のノードに対して一貫した方法でテキストコンテンツの取得や設定を行うための標準的な手段を提供します。これにより、DOMツリーの操作がより直感的で堅牢になります。
構文(syntax)
1<?php 2$dom = new DOMDocument(); 3$element = $dom->createElement('example'); 4$textNode = $dom->createTextNode('Hello, PHP DOM!'); 5$element->appendChild($textNode); 6$dom->appendChild($element); 7 8// textContent プロパティを読み取る 9echo $textNode->textContent; 10 11// textContent プロパティを書き込む 12$textNode->textContent = 'Updated text content.'; 13echo $textNode->textContent; 14?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
DOMCharacterDataノードに含まれるテキストコンテンツを文字列として返します。このプロパティは、ノードのtextContent属性の値を操作するために使用されます。
サンプルコード
PHP DOMDocument textContentでテキスト操作
1<?php 2 3/** 4 * DOMCharacterData::textContent プロパティの基本的な使用方法をデモンストレーションします。 5 * 6 * DOMCharacterData は、テキストノード (DOMText) やコメントノード (DOMComment) の 7 * 基底クラスであり、これらのノードのテキストコンテンツにアクセスするために使用されます。 8 * textContent プロパティは、ノードのデータ(テキスト内容)を取得および設定できます。 9 */ 10function demonstrateDomTextContent(): void 11{ 12 // 新しい DOMDocument インスタンスを作成します。 13 // XML バージョンとエンコーディングを指定します。 14 $dom = new DOMDocument('1.0', 'UTF-8'); 15 // 出力時にXMLを整形 (インデントなど) するよう設定します。 16 $dom->formatOutput = true; 17 18 // ルート要素を作成し、DOMDocument に追加します。 19 $rootElement = $dom->createElement('example'); 20 $dom->appendChild($rootElement); 21 22 // --- DOMText ノードでの textContent の使用例 --- 23 24 // DOMText ノードを作成します。DOMText は DOMCharacterData を継承しています。 25 $textNode = $dom->createTextNode('これは元のテキストです。'); 26 $rootElement->appendChild($textNode); 27 28 echo "--- DOMText の例 ---\n"; 29 // textContent プロパティを使用して、テキストノードの内容を取得します。 30 echo "取得したテキスト (変更前): " . $textNode->textContent . "\n"; 31 32 // textContent プロパティを使用して、テキストノードの内容を変更します。 33 $textNode->textContent = 'これは新しいテキストです。'; 34 echo "取得したテキスト (変更後): " . $textNode->textContent . "\n"; 35 36 // --- DOMComment ノードでの textContent の使用例 --- 37 38 // DOMComment ノードを作成します。DOMComment も DOMCharacterData を継承しています。 39 $commentNode = $dom->createComment('これは元のコメントです。'); 40 $rootElement->appendChild($commentNode); 41 42 echo "\n--- DOMComment の例 ---\n"; 43 // textContent プロパティを使用して、コメントノードの内容を取得します。 44 echo "取得したコメント (変更前): " . $commentNode->textContent . "\n"; 45 46 // textContent プロパティを使用して、コメントノードの内容を変更します。 47 $commentNode->textContent = 'これは新しいコメントです。'; 48 echo "取得したコメント (変更後): " . $commentNode->textContent . "\n"; 49 50 // (オプション)完成したDOMをXMLとして出力し、変更を確認します。 51 // echo "\n--- 生成されたXML ---\n"; 52 // echo $dom->saveXML(); 53} 54 55// 関数を実行してデモンストレーションを開始します。 56demonstrateDomTextContent(); 57 58?>
PHPのDOMCharacterData::textContentプロパティは、XMLやHTML文書の構造を操作するDOM(Document Object Model)において、ノードが持つテキスト内容を取得したり、新しく設定したりするために使用されます。DOMCharacterDataクラスは、DOMText(文書内の通常のテキスト)やDOMComment(コメント)といった、文字データを直接扱うノードの基底となるクラスです。
このtextContentプロパティでノードのテキスト内容を取得する際には、特に引数を指定する必要はありません。ノードが持つテキストデータを文字列(string)として返します。また、このプロパティに新しい文字列を代入することで、ノードのテキスト内容を変更・設定することも可能です。
サンプルコードでは、DOMDocumentを使用してHTMLやXMLの構造を模倣し、DOMTextノードとDOMCommentノードを作成しています。それぞれのノードに対して、まずtextContentプロパティを使って現在の内容を取得し、その後に別の文字列を代入して内容を変更し、再度textContentで変更後の内容を取得・表示する一連の操作を具体的に示しています。これにより、テキストノードやコメントノードのデータを簡単に読み書きできることが確認できます。
DOMCharacterData::textContentは、テキストノードやコメントノードの純粋なテキスト内容を直接取得・設定する際に使用します。このプロパティに文字列を設定すると、入力された内容がHTMLタグであってもそのままテキストデータとして扱われ、タグとして解釈されません。そのため、HTMLタグを含む文字列を設定しても、そのタグはブラウザで表示される際にただのテキストとして表示されます。
また、もし要素ノード(DOMElement)に対してtextContentを設定した場合、その要素内に存在するすべての子ノード(テキスト、要素、コメントなど)が削除され、設定されたテキストのみを含む新しいテキストノードが挿入されます。これにより、既存のDOM構造が大きく変わる可能性があるため注意が必要です。
ユーザーからの入力値など外部からの文字列をtextContentに設定し、後でその内容をHTMLとして出力する際は、クロスサイトスクリプティング(XSS)などのセキュリティリスクを避けるため、出力時に適切なエスケープ処理を検討してください。
PHP DOM: textContentとnodeValueの比較
1<?php 2 3/** 4 * DOMNode の textContent と nodeValue プロパティの挙動の違いをデモンストレーションします。 5 * 主に DOMElement, DOMText, DOMComment の3種類のノードで比較を行います。 6 */ 7function demonstrateTextContentVsNodeValue(): void 8{ 9 // 比較に使用するHTML文字列を定義 10 $html = <<<HTML 11 <div id="example-container"> 12 <!-- これはテスト用のコメントノードです --> 13 <p> 14 これはメインのテキストです。 15 <span>さらに内側のテキストです。</span> 16 <br> 17 そして、続くテキストです。 18 </p> 19 <span>直接の子スパンです。</span> 20 <div>ネストされたdiv内のテキスト。</div> 21 テキストノードの直接のコンテンツ。 22 </div> 23 HTML; 24 25 // DOMDocument オブジェクトを作成し、HTMLをロード 26 $dom = new DOMDocument(); 27 // HTMLパース時の警告を抑制します(不正なHTMLでも処理を続行するため) 28 libxml_use_internal_errors(true); 29 $dom->loadHTML($html); 30 libxml_clear_errors(); // エラー抑制を解除 31 32 echo "--- DOMNode の textContent と nodeValue の比較 ---" . PHP_EOL; 33 echo "(ノードの種類によって取得される値が異なります)" . PHP_EOL . PHP_EOL; 34 35 // 1. ルート要素として #example-container を取得 (DOMElement) 36 $container = $dom->getElementById('example-container'); 37 if ($container) { 38 echo "### ノード: <div id=\"example-container\">...</div> (DOMElement) ###" . PHP_EOL; 39 // textContent: この要素とすべての子孫要素のテキスト内容を連結して返します。HTMLタグは無視されます。 40 echo "textContent: " . var_export($container->textContent, true) . PHP_EOL; 41 // nodeValue: DOMElement の場合、常に null を返します。 42 echo "nodeValue: " . var_export($container->nodeValue, true) . PHP_EOL; 43 echo PHP_EOL; 44 } 45 46 // 2. 最初の <p> 要素を取得 (DOMElement) 47 $paragraph = $dom->getElementsByTagName('p')->item(0); 48 if ($paragraph) { 49 echo "### ノード: <p>...</p> (DOMElement) ###" . PHP_EOL; 50 // textContent: <p>タグ内のすべてのテキストを結合して返します。 51 echo "textContent: " . var_export($paragraph->textContent, true) . PHP_EOL; 52 // nodeValue: DOMElement のため null です。 53 echo "nodeValue: " . var_export($paragraph->nodeValue, true) . PHP_EOL; 54 echo PHP_EOL; 55 56 // 3. <p> 要素内のテキストノードを取得 (DOMText) 57 // ここでは最初の非空白テキストノードを探します 58 $firstTextInP = null; 59 foreach ($paragraph->childNodes as $childNode) { 60 // テキストノードであり、かつ内容が空でないもの 61 if ($childNode->nodeType === XML_TEXT_NODE && trim($childNode->nodeValue) !== '') { 62 $firstTextInP = $childNode; 63 break; 64 } 65 } 66 if ($firstTextInP) { 67 echo "### ノード: <p>内のテキストノード (\"これはメインのテキストです。\"...) (DOMText) ###" . PHP_EOL; 68 // textContent: DOMText の場合、自身のテキスト内容を返します。 69 echo "textContent: " . var_export($firstTextInP->textContent, true) . PHP_EOL; 70 // nodeValue: DOMText の場合、自身のテキスト内容を返します。textContent と同じになります。 71 echo "nodeValue: " . var_export($firstTextInP->nodeValue, true) . PHP_EOL; 72 echo PHP_EOL; 73 } 74 75 // 4. <p> 要素内の <span> 要素を取得 (DOMElement) 76 $innerSpan = $paragraph->getElementsByTagName('span')->item(0); 77 if ($innerSpan) { 78 echo "### ノード: <span>さらに内側のテキストです。</span> (DOMElement) ###" . PHP_EOL; 79 // textContent: <span>タグ内のテキストを返します。 80 echo "textContent: " . var_export($innerSpan->textContent, true) . PHP_EOL; 81 // nodeValue: DOMElement のため null です。 82 echo "nodeValue: " . var_export($innerSpan->nodeValue, true) . PHP_EOL; 83 echo PHP_EOL; 84 } 85 } 86 87 // 5. コメントノードを取得 (DOMComment) 88 // #example-container の子ノードからコメントを探します 89 $commentNode = null; 90 if ($container) { 91 foreach ($container->childNodes as $childNode) { 92 if ($childNode->nodeType === XML_COMMENT_NODE) { 93 $commentNode = $childNode; 94 break; 95 } 96 } 97 } 98 if ($commentNode) { 99 echo "### ノード: <!-- これはテスト用のコメントノードです --> (DOMComment) ###" . PHP_EOL; 100 // textContent: DOMComment の場合、コメント内容を返します。 101 echo "textContent: " . var_export($commentNode->textContent, true) . PHP_EOL; 102 // nodeValue: DOMComment の場合、コメント内容を返します。textContent と同じになります。 103 echo "nodeValue: " . var_export($commentNode->nodeValue, true) . PHP_EOL; 104 echo PHP_EOL; 105 } 106 107 // 6. <div> の直下にあるテキストノード (DOMText) 108 // 「テキストノードの直接のコンテンツ。」という部分 109 $directTextNode = null; 110 if ($container) { 111 foreach ($container->childNodes as $childNode) { 112 if ($childNode->nodeType === XML_TEXT_NODE && trim($childNode->nodeValue) === 'テキストノードの直接のコンテンツ。') { 113 $directTextNode = $childNode; 114 break; 115 } 116 } 117 } 118 if ($directTextNode) { 119 echo "### ノード: <div>直下のテキストノード (\"テキストノードの直接のコンテンツ。\") (DOMText) ###" . PHP_EOL; 120 // textContent: DOMText の場合、自身のテキスト内容を返します。 121 echo "textContent: " . var_export($directTextNode->textContent, true) . PHP_EOL; 122 // nodeValue: DOMText の場合、自身のテキスト内容を返します。textContent と同じになります。 123 echo "nodeValue: " . var_export($directTextNode->nodeValue, true) . PHP_EOL; 124 echo PHP_EOL; 125 } 126} 127 128// 関数を実行してデモンストレーションを開始 129demonstrateTextContentVsNodeValue();
PHPのDOM操作において、textContentプロパティは、指定されたノードとそのすべての子孫ノードが持つテキストコンテンツをまとめて取得するために使用されます。このプロパティは引数を取らず、結果として結合されたテキスト内容を一つの文字列として返します。
特に、HTML要素全体を表すDOMElementノードに対してtextContentを使用すると、その要素自身と、その中に含まれる全ての子孫要素(例えば、<p>タグ内の<span>タグなども含む)の純粋なテキスト部分が連結されて返されます。この際、HTMLタグそのものは含まれません。一方、DOMElementのnodeValueプロパティは常にnullを返します。
これに対し、純粋なテキストを表すDOMTextノードやコメントを表すDOMCommentノードの場合、textContentはそのノードが直接持つテキスト内容やコメント内容をそのまま返します。これらの特定のノードタイプでは、nodeValueプロパティもtextContentプロパティと全く同じ内容の文字列を返します。
サンプルコードは、これらの異なるノードタイプに対してtextContentとnodeValueがどのように振る舞うかを具体的に示しています。特に、ある要素の内部にあるテキストをまとめて簡単に抽出したい場合に、textContentプロパティは非常に役立ちます。
PHPのDOM操作では、textContentとnodeValueの挙動に注意が必要です。textContentは要素ノードの場合、その要素と全ての子孫要素内のテキスト内容を結合して返します。HTMLタグは無視されるため、要素内の可視テキスト全体を取得したい場合に適しています。しかし、nodeValueは要素ノードに対しては常にnullを返しますので、要素からテキストコンテンツを取得する目的では使用できません。
一方、テキストノードやコメントノードでは、textContentとnodeValueはどちらもノード自身のテキスト内容を返します。このため、ノードの種類を理解し、要素から広範囲のテキストを取得するならtextContent、特定のテキストノードやコメントノードの内容を取得するなら両方利用できると覚えておくと良いでしょう。