【PHP8.x】DOMText::wholeTextプロパティの使い方
wholeTextプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
wholeTextプロパティは、DOMTextノードが保持するテキスト全体を文字列として取得または設定するためのプロパティです。DOMTextは、XMLやHTMLドキュメント内のテキストを表すノードであり、通常、要素(タグ)間のテキストコンテンツとして存在します。
このプロパティを使用することで、複数の隣接するDOMTextノードが結合されたテキスト全体をまとめて取得できます。例えば、ある要素の中に複数のテキストノードが連続して存在する場合、wholeTextプロパティは、これらのノードの内容を連結した文字列を返します。
テキストノードの内容を書き換えることも可能です。wholeTextプロパティに新しい文字列を代入すると、隣接するすべてのDOMTextノードが削除され、新しいテキスト内容を持つ単一のDOMTextノードに置き換えられます。これにより、ドキュメントの構造を維持しながら、テキストコンテンツを効率的に変更できます。
DOMDocumentオブジェクトを操作する際に、テキストノードの取得や変更を簡単に行うことができるため、XMLやHTMLドキュメントの解析や編集を行うシステムを開発する際に役立ちます。このプロパティを利用することで、テキストノードの扱いが簡略化され、より直感的なコード記述が可能になります。PHPでXMLやHTMLを扱う場合は、DOMTextオブジェクトと合わせて、このwholeTextプロパティの挙動を理解しておくことを推奨します。
構文(syntax)
1DOMText::$wholeText;
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
DOMTextノードに含まれる全テキストコンテンツを文字列として返します。
サンプルコード
HTMLテキストノードの数字のみチェック
1<?php 2 3/** 4 * HTML文字列からDOMTextノードを抽出し、 5 * そのwholeTextプロパティで取得したテキストが数字のみで構成されているかを確認します。 6 * 7 * DOMText::wholeText プロパティは、現在のテキストノードとその論理的に隣接する 8 * (間に要素ノードなどを挟まない) テキストノードの結合されたコンテンツを返します。 9 * 例えば、`<div>123<!--comment-->456</div>` の場合、`123` のテキストノードの 10 * wholeText は "123456" となります。 11 * 12 * @param string $htmlContent 処理対象のHTML文字列。 13 */ 14function checkNumericWholeTextInHtml(string $htmlContent): void 15{ 16 // DOMDocumentのインスタンスを作成 17 $dom = new DOMDocument(); 18 19 // HTML文字列をロードします。 20 // LIBXML_HTML_NOIMPLIED と LIBXML_HTML_NODEFDTD は、 21 // 短いHTMLスニペットを処理する際に、不要な<html>や<body>タグが自動的に追加されるのを防ぎます。 22 // エラーが発生しても処理を継続するために @ を付けて抑制しています。 23 @$dom->loadHTML($htmlContent, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 24 25 // XPathを使ってドキュメント内のすべてのテキストノードを選択します。 26 // "//text()" は、ドキュメントツリー内のどこにあってもすべてのDOMTextノードにマッチします。 27 $xpath = new DOMXPath($dom); 28 $textNodes = $xpath->query('//text()'); 29 30 echo "--- HTMLから抽出したテキストノードの数字のみチェック ---\n"; 31 echo "対象HTML: \"" . htmlspecialchars($htmlContent) . "\"\n\n"; 32 33 if ($textNodes->length === 0) { 34 echo "テキストノードが見つかりませんでした。\n"; 35 return; 36 } 37 38 foreach ($textNodes as $textNode) { 39 // 現在のノードが DOMText のインスタンスであることを確認します。 40 if ($textNode instanceof DOMText) { 41 // DOMText::wholeText プロパティを使用して、現在のテキストノードとその 42 // 論理的に隣接するテキストノードの結合されたテキストコンテンツを取得します。 43 $fullText = $textNode->wholeText; 44 45 // ctype_digit() は、文字列がすべて数字(0-9)で構成されているかをチェックします。 46 // 空文字列や、空白、負の数、小数点を含む文字列に対しては false を返します。 47 $isNumericOnly = ctype_digit($fullText); 48 49 echo " ノード値 (nodeValue): '{$textNode->nodeValue}'\n"; // このノード自身のテキスト 50 echo " 抽出テキスト (wholeText): '{$fullText}'\n"; // 隣接ノードも結合されたテキスト 51 if ($isNumericOnly) { 52 echo " -> 数字のみです。\n"; 53 } else { 54 echo " -> 数字のみではありません。\n"; 55 } 56 echo "-------------------------------------\n"; 57 } 58 } 59} 60 61// --- 使用例 --- 62 63// ケース1: 数字のみのテキスト 64checkNumericWholeTextInHtml('<div>1234567890</div>'); 65 66// ケース2: 数字と非数字が混在するテキスト 67checkNumericWholeTextInHtml('<div>電話番号: 090-1234-5678</div>'); 68 69// ケース3: 複数行の数字を含むテキスト(通常は一つのDOMTextノードとして処理される) 70checkNumericWholeTextInHtml("<div>111\n222333</div>"); 71 72// ケース4: コメントノードで区切られた数字(wholeTextが隣接するテキストノードを結合する例) 73// "123" は最初のDOMTextノード、"456" は次のDOMTextノードです。 74// `wholeText` はこれらを結合して "123456" を返します。 75checkNumericWholeTextInHtml('<div>123<!--これはコメント-->456</div>'); 76 77// ケース5: 数字の間に要素ノードが挟まっている場合(wholeTextは結合しない例) 78// `<span>` 要素がテキストノードではないため、`123` と `789` は論理的に隣接していません。 79// それぞれの `wholeText` はそのノード自身のテキスト "123" と "789" を返します。 80checkNumericWholeTextInHtml('<div>123<span>中間</span>789</div>'); 81 82// ケース6: 空白のみのテキスト (ctype_digitはfalse) 83checkNumericWholeTextInHtml('<div> </div>'); 84 85// ケース7: 空のテキスト (ctype_digitはfalse) 86checkNumericWholeTextInHtml('<div></div>');
PHP 8のDOMText::wholeTextプロパティは、HTMLドキュメント内のテキストコンテンツを効率的に取得するための機能です。このプロパティは、現在のテキストノードだけでなく、その論理的に隣接する(間に要素ノードなどを挟まない)テキストノードのコンテンツも結合して、一つのまとまった文字列として返します。例えば、<div>123<!--コメント-->456</div>のようなHTML構造で「123」のテキストノードのwholeTextプロパティにアクセスすると、「123456」という文字列が取得されます。一方、nodeValueプロパティはそのテキストノード自身のコンテンツのみを返します。
このプロパティは引数を取らず、常に文字列(string)を戻り値として返します。提供されたサンプルコードでは、HTML文字列からDOMTextノードを抽出し、そのwholeTextプロパティで取得したテキストが「数字のみ」で構成されているかを確認しています。数字のみの判定にはctype_digit()関数が使われており、この関数は文字列が全て0から9の数字で構成されている場合にのみtrueを返します。wholeTextを活用することで、複数のテキストノードに分断された数字列でも一括で処理し、数字のみの検証を簡潔に行うことが可能です。
DOMText::wholeTextプロパティは、現在のノードと論理的に隣接するテキストノード(要素ノードなどを挟まない)を結合したテキストを返します。コメントノードは結合を妨げませんが、他の要素ノードが間にあるとテキストは結合されません。これはnodeValueとは異なる振る舞いですので、混同しないよう注意してください。ctype_digit()関数は、文字列がすべて数字(0-9)のみで構成されているかを厳密に確認します。空文字列や空白、小数点、負の数を含む文字列は「数字のみ」と判定されませんので、意図する結果か確認が必要です。また、DOMDocument::loadHTML()のエラー抑制記号「@」は一時的なものであり、実運用では適切なエラーハンドリングを実装することが安全で堅牢なコードに繋がります。
PHP DOMText::wholeTextをwhile(true)で処理する
1<?php 2 3/** 4 * HTML文字列からDOMTextノードを抽出し、 5 * そのwholeTextプロパティを出力するサンプル関数です。 6 * 7 * キーワード「while(true)」に合わせ、無限ループとbreak文を使ってノードリストを処理する例を示します。 8 * PHPでは通常、DOMNodeListの反復処理にはforeachループを使用するのがより一般的で推奨されます。 9 * 10 * @param string $html HTML文字列 11 * @return void 12 */ 13function processDomTextWithWhileTrue(string $html): void 14{ 15 $dom = new DOMDocument(); 16 17 // libxmlのエラーを内部で処理し、警告が出ないように設定します。 18 // これにより、HTMLのパースエラーが画面に表示されなくなります。 19 libxml_use_internal_errors(true); 20 // HTMLをDOMDocumentに読み込みます。 21 // LIBXML_HTML_NOIMPLIED と LIBXML_HTML_NODEFDTD は、 22 // 余分な<html>や<!DOCTYPE>タグの自動追加を抑制します。 23 $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 24 libxml_use_internal_errors(false); // エラー処理を元の設定に戻す 25 26 // DOMXPathオブジェクトを作成し、XPathクエリで全てのテキストノードを取得します。 27 // '//text()' はDOMツリー内の全てのテキストノードを選択します。 28 $xpath = new DOMXPath($dom); 29 $textNodes = $xpath->query('//text()'); 30 31 $index = 0; 32 // キーワード「while(true)」に合わせ、無限ループとbreak文を使ってノードリストを処理します。 33 // 通常、DOMNodeListの反復処理には foreach($textNodes as $node) を使用するのが推奨されます。 34 while (true) { 35 // ノードリストのインデックスが範囲外になったらループを終了します。 36 if (!isset($textNodes[$index])) { 37 break; 38 } 39 40 // 現在のインデックスにあるノードを取得します。 41 $node = $textNodes[$index]; 42 43 // 取得したノードがDOMTextのインスタンスであることを確認します。 44 if ($node instanceof DOMText) { 45 echo "DOMTextノードが見つかりました:\n"; 46 // nodeValueはノード自身のテキストコンテンツを返します。 47 echo " nodeValue: " . $node->nodeValue . "\n"; 48 // wholeTextは、このノードに隣接する全てのテキストノードを結合した 49 // 完全なテキストコンテンツを返します。 50 // (ただし、間に要素ノード、コメントノード、処理命令などが入ると、 51 // その前後でテキストの連続性が途切れます。) 52 echo " wholeText: " . $node->wholeText . "\n"; 53 echo "--------------------\n"; 54 } 55 56 $index++; // 次のノードへ進む 57 } 58 59 echo "DOMTextノードの処理が完了しました。\n"; 60} 61 62// サンプルとして使用するHTML文字列 63$sampleHtml = <<<HTML 64<!DOCTYPE html> 65<html> 66<head> 67 <title>DOMText::wholeTextのサンプル</title> 68</head> 69<body> 70 <h1>Hello <!--コメント--> World!</h1> 71 <p>これは<span>一部の</span>テキストです。そして<br>別の部分です。</p> 72 <p>連続したテキスト1<span style="display:none;">隠しテキスト</span>連続したテキスト2</p> 73 <p> 74 Line 1 75 <!-- コメント --> 76 Line 2 77 </p> 78</body> 79</html> 80HTML; 81 82// 関数を実行して結果を出力します 83processDomTextWithWhileTrue($sampleHtml);
このPHPコードは、HTMLドキュメントからテキストノードを抽出し、PHP 8で導入されたDOMTextクラスのwholeTextプロパティの挙動を示すものです。wholeTextプロパティは引数を持たず、現在のテキストノードと、間に要素ノードやコメントノードなどを挟まずに直前または直後に隣接するテキストノードすべてを結合した、連続するテキスト全体の文字列を戻り値として返します。
コードではまず、与えられたHTML文字列をDOMDocumentオブジェクトとして読み込み、XPathを使ってドキュメント内のすべてのテキストノードを検索し、取得しています。キーワードである「while(true)」に合わせ、無限ループとbreak文を使用して、取得したテキストノードリストを順に処理する例を示していますが、PHPでDOMノードリストを反復処理する際には、通常はより簡潔で推奨されるforeach文を使用します。
ループ内で各テキストノードにアクセスし、そのノード自身のテキストコンテンツを返すnodeValueプロパティと、連続するテキスト全体を返すwholeTextプロパティの両方を出力しています。これにより、nodeValueがそのテキストノード単独の内容であるのに対し、wholeTextが周囲のテキストのつながりを考慮した内容であることが理解できます。例えば、「これは<span>一部の</span>テキストです。」のような構造では、「これは」と「テキストです。」は別々のDOMTextノードですが、それぞれのwholeTextは隣接するテキストがなければnodeValueと同じ値になります。このコードは、HTML構造におけるテキストの連続性と、それらをPHPのDOM拡張機能でどのように扱うかを学ぶのに役立ちます。
このサンプルコードで示されたwhile(true)とbreakによるループ処理は、DOMNodeListの操作において一般的ではありません。通常はforeachループを使用することが推奨され、より安全で可読性が高いです。DOMText::wholeTextプロパティは、このテキストノードに隣接する連続したテキストノード全体を結合した文字列を返します。ただし、間に要素やコメントノードなどが挟まると、その前後でテキストの連続性は途切れるため、nodeValueとの違いを理解して使い分けることが大切です。また、libxml_use_internal_errors(true)はHTMLパース時の警告を抑制しますが、エラー自体を解決するものではありません。実際のシステム開発では、エラー内容を適切に処理・記録するよう心がけてください。