【PHP8.x】nodeValueプロパティの使い方
nodeValueプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
nodeValueプロパティは、Dom\Elementクラスに属し、HTMLやXMLドキュメント内の要素のテキストコンテンツを保持するプロパティです。Dom\Elementクラスは、HTMLにおける<p>タグや<div>タグのように、タグで囲まれた一つのまとまりである「要素ノード」を表します。
このnodeValueプロパティを利用すると、対象となる要素ノードに含まれるすべてのテキスト情報を、子要素のタグ構造を考慮せずに、単一の連結された文字列として読み取ることが可能です。例えば、ある<div>タグの中に複数の子要素やテキストが混在していても、その<div>タグのnodeValueプロパティを参照すれば、その<div>タグ内に存在する純粋なテキスト部分だけをまとめて取得できます。
また、このプロパティに新しい文字列を設定することで、要素ノード内の既存のテキストコンテンツを置き換えることもできます。これにより、プログラムから動的にウェブページのテキストを変更したり、XMLデータの文字列内容を操作したりする際に非常に強力な機能となります。システムエンジニアとしてDOM(Document Object Model)を操作する際には、要素の内部テキストを効率的に取得したり設定したりするための基本的な機能として、このnodeValueプロパティは頻繁に活用されます。
構文(syntax)
1<?php 2$document = new Dom\Document(); 3$element = $document->createElement('tag', 'テキスト内容'); 4echo $element->nodeValue; 5?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
この nodeValue プロパティは、XMLまたはHTMLドキュメントのノードのテキストコンテンツを返します。ノードがテキストノードでない場合や、テキストコンテンツが存在しない場合は null を返します。
サンプルコード
PHP DOM nodeValueでテキスト取得
1<?php 2 3/** 4 * Dom\ElementのnodeValueプロパティを使用してテキストコンテンツを取得するサンプル関数です。 5 */ 6function demonstrateNodeValueProperty(): void 7{ 8 // 解析対象のHTML文字列を準備します。 9 // <p>タグの中のテキストを取得することが目的です。 10 $html = ' 11 <div> 12 <h1>PHP DOM サンプル</h1> 13 <p>こんにちは、世界!</p> 14 </div> 15 '; 16 17 // DOMDocumentオブジェクトをインスタンス化します。 18 // これはHTMLやXMLドキュメントを操作するための基点となります。 19 $doc = new \DOMDocument(); 20 21 // HTML文字列を読み込み、DOMツリーを構築します。 22 // 不完全なHTMLでも、このメソッドが自動的に補完してくれます。 23 // HTML5のタグなどに関する警告が表示されるのを防ぐため、libxmlのエラー処理を制御します。 24 libxml_use_internal_errors(true); 25 $doc->loadHTML($html); 26 libxml_clear_errors(); 27 28 // getElementsByTagName()メソッドで、ドキュメント内の全ての<p>要素を取得します。 29 // 戻り値はDOMNodeListオブジェクト(要素のリスト)です。 30 $pElements = $doc->getElementsByTagName('p'); 31 32 // リストの最初の要素を取得します (item(0))。 33 // 要素が見つかれば、それはDom\Elementオブジェクトです。 34 $firstP = $pElements->item(0); 35 36 // 要素が正しく取得できたかを確認します。 37 if ($firstP instanceof \DOMElement) { 38 // nodeValueプロパティにアクセスして、要素内のテキストコンテンツを取得します。 39 // この場合、<p>こんにちは、世界!</p> の中の「こんにちは、世界!」という文字列が返されます。 40 $textValue = $firstP->nodeValue; 41 42 // 取得した値を出力します。 43 // PHP_EOLは実行環境に合わせた改行コードを出力します。 44 echo $textValue . PHP_EOL; 45 } 46} 47 48// 関数を実行します。 49demonstrateNodeValueProperty();
Dom\Elementクラスが持つnodeValueプロパティは、HTMLやXMLの特定の要素(タグ)とその子孫が持つテキストコンテンツを取得するために使用します。このプロパティにアクセスする際、引数は必要ありません。戻り値として、要素内に存在するテキストが文字列(string)として返されます。テキストが存在しない場合はnullを返します。
サンプルコードでは、まずDOMDocumentオブジェクトを利用してHTML文字列を解析し、プログラムで扱いやすいデータ構造に変換しています。次にgetElementsByTagName('p')メソッドで全ての<p>要素を取得し、その中から最初の要素を取り出します。そして、その<p>要素オブジェクトのnodeValueプロパティにアクセスすることで、タグに囲まれたテキスト「こんにちは、世界!」を取得しています。このようにnodeValueプロパティは、特定のHTML要素からテキスト情報だけを簡単かつ正確に抽出したい場合に非常に便利な機能です。
getElementsByTagNameで要素が見つからない場合、item(0)はnullを返すため、nodeValueプロパティにアクセスするとエラーになります。処理の前に必ずif文などで要素の存在を確認してください。また、nodeValueは指定した要素だけでなく、その子孫要素が持つ全てのテキストを連結して取得します。例えば<p>テキスト<span>もっとテキスト</span></p>という構造からは「テキストもっとテキスト」という一つの文字列が返されます。このため、意図しないテキストが含まれないかHTMLの構造を意識することが重要です。HTMLタグ自体は含まれず、テキストコンテンツのみが対象となります。
PHP nodeValue vs textContent を比較する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOMElementの `nodeValue` と `textContent` プロパティの違いを比較します。 7 * 8 * `nodeValue` と `textContent` は、要素内のテキストを取得する際によく混同されますが、 9 * 挙動が大きく異なります。このサンプルでは、その違いを明確に示します。 10 */ 11function compareNodeValueAndTextContent(): void 12{ 13 // 比較対象となるHTML文字列を定義します。 14 // <p>要素は、テキストノードと<strong>要素ノードを子として持っています。 15 $html = '<p>これは<strong>重要</strong>なテキストです。</p>'; 16 17 // DOMDocumentオブジェクトをインスタンス化します。 18 $dom = new DOMDocument(); 19 20 // HTMLを読み込み、DOMツリーを構築します。 21 // 文字化けを防ぐため、XML宣言を追加しています。 22 // LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD は、<html>や<body>タグが自動で追加されるのを防ぐオプションです。 23 @$dom->loadHTML('<?xml encoding="utf-8" ?>' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 24 25 // getElementsByTagNameで<p>要素を取得します。 26 // 戻り値はDOMNodeListなので、item(0)で最初の要素(DOMElement)を取得します。 27 $pElement = $dom->getElementsByTagName('p')->item(0); 28 29 // --- 1. nodeValue プロパティの挙動 --- 30 // 要素ノード(DOMElement)に対して `nodeValue` を参照すると、仕様により常に `null` が返されます。 31 // これは、要素自体が単一の「値」を持つのではなく、子ノードの集合体であるためです。 32 $nodeValueResult = $pElement->nodeValue; 33 34 // --- 2. textContent プロパティの挙動 --- 35 // `textContent` は、その要素自身と、すべての子孫ノード(子要素、孫要素など)の 36 // テキストコンテンツを連結した文字列を返します。途中のHTMLタグはすべて取り除かれます。 37 // 一般的に「要素内のテキストをまとめて取得したい」という場合に期待される動作はこちらです。 38 $textContentResult = $pElement->textContent; 39 40 // --- 結果の出力 --- 41 echo 'HTML: ' . $html . PHP_EOL; 42 echo '-----------------------------------------------' . PHP_EOL; 43 44 echo 'pElement->nodeValue の結果:' . PHP_EOL; 45 var_dump($nodeValueResult); // 出力: NULL 46 47 echo PHP_EOL; 48 49 echo 'pElement->textContent の結果:' . PHP_EOL; 50 var_dump($textContentResult); // 出力: string(45) "これは重要なテキストです。" 51} 52 53// 関数を実行します。 54compareNodeValueAndTextContent();
Dom\ElementクラスのnodeValueプロパティは、ノードの値を取得しますが、要素ノード(HTMLタグに相当)に対して使用した場合は、仕様により常にnullを返します。これは、要素自体が単一の「値」を持つのではなく、テキストや他の要素といった子ノードを格納するコンテナとしての役割を持つためです。このプロパティに引数はなく、戻り値はノードの種類によって文字列またはnullとなります。
サンプルコードでは、<p>という要素ノードからnodeValueを取得しているため、結果はnullになります。
一方、よく比較されるtextContentプロパティは、その要素自身と、その配下にあるすべての子孫ノードのテキストを連結した一つの文字列を返します。途中のHTMLタグはすべて取り除かれます。サンプルコードで「これは重要なテキストです。」という文字列が取得できているのはこのためです。一般的に、要素内のテキスト全体をまとめて取得したい場合にはtextContentを使用するのが適切です。
HTMLタグのような要素からテキストを取得する際、nodeValueプロパティを使うと意図に反して常にnullが返される点に注意が必要です。これは、nodeValueが要素ノードに対しては値を返さないという仕様のためです。サンプルコードのように、要素とその子孫が含む全てのテキストをタグを除いて文字列として取得したい場合は、textContentプロパティを使用するのが一般的です。nodeValueはテキストそのものを表すノード(テキストノード)など、特定種類のノードの値を取得する際に有効です。また、getElementsByTagNameで要素が見つからないとitem(0)はnullを返すため、プロパティにアクセスする前に存在チェックを行うと、より安全なコードになります。