【PHP8.x】innerHTMLプロパティの使い方
innerHTMLプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
innerHTMLプロパティは、DOM要素の内部にあるHTMLマークアップ全体を取得または設定するために使用できる、Dom\Elementクラスのプロパティです。このプロパティを使用することで、要素の子要素を含むHTMLコンテンツを文字列として操作できます。
具体的には、innerHTMLプロパティに値を代入すると、その要素の既存の子要素がすべて削除され、指定された文字列に基づいて新しいDOMツリーが構築されます。逆に、innerHTMLプロパティの値を読み出すと、その要素の子要素を表現するHTML文字列が返されます。
このプロパティは、Webページ上で動的にコンテンツを更新する際に非常に便利です。例えば、サーバーから取得したデータを基にHTML構造を生成し、それを特定の要素内に表示させたい場合に、innerHTMLプロパティを使って簡単に実現できます。
ただし、innerHTMLプロパティを使用する際には、クロスサイトスクリプティング(XSS)攻撃のリスクに注意が必要です。信頼できないソースからのデータに基づいてinnerHTMLを更新すると、悪意のあるスクリプトが実行される可能性があります。そのため、外部からの入力データをinnerHTMLに設定する前に、適切にエスケープ処理を行うなどのセキュリティ対策を講じることが重要です。
innerHTMLプロパティは、DOM操作において強力なツールですが、セキュリティ上の注意点も理解した上で、適切に使用する必要があります。安全なWebアプリケーションを開発するために、入力データの検証とエスケープ処理を徹底することが推奨されます。
構文(syntax)
1<?php 2 3$document = new Dom\Document(); 4// HTML文字列を読み込む(<html><body>タグは自動的に補完される) 5$document->loadHTML('<div id="main">これは元のテキストです。</div>'); 6 7// id="main" を持つ Dom\Element を取得 8$element = $document->getElementById('main'); 9 10// innerHTML プロパティを読み取る 11$current_html = $element->innerHTML; // "これは元のテキストです。" 12 13// innerHTML プロパティを書き換える 14$element->innerHTML = '<b>太字の新しいテキスト</b>'; 15 16// 変更後のHTML全体を出力する 17echo $document->saveHTML();
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
Dom\Element::innerHTML は、要素の内部に含まれる HTML 文字列を返します。
サンプルコード
PHP DOM innerHTML を取得する
1<?php 2 3use Dom\Document; 4use Dom\Element; 5 6/** 7 * Dom\Element クラスの innerHTML プロパティを取得するサンプルコードです。 8 * 9 * この関数は、PHP 8 で導入された新しい Dom 拡張(Dom 名前空間)を使用しています。 10 * innerHTML は、要素内の HTML コンテンツを文字列として返します。 11 */ 12function getDomElementInnerHtmlExample(): void 13{ 14 // 1. 新しい Dom\Document インスタンスを作成します。 15 // Dom\Document は HTML や XML ドキュメントを扱うためのクラスです。 16 $dom = new Document(); 17 18 // 2. HTML コンテンツをドキュメントにロードします。 19 // loadHtml() メソッドは、指定された HTML 文字列を解析し、DOM ツリーを構築します。 20 $htmlContent = '<div id="container"> 21 <p>こんにちは、<strong>世界</strong>!</p> 22 <span>これはテストです。</span> 23 </div> 24 <span id="simpleTextElement">単純なテキスト</span>'; 25 $dom->loadHtml($htmlContent); 26 27 // 3. ID を使用して特定の Dom\Element を取得します。 28 // getElementById() メソッドは、指定された ID を持つ Dom\Element インスタンス(または見つからなかった場合は null)を返します。 29 $element = $dom->getElementById('container'); 30 31 // 要素が正常に見つかったかを確認します。 32 if ($element instanceof Element) { 33 // 4. Dom\Element の innerHTML プロパティにアクセスします。 34 // innerHTML プロパティは、要素内の HTML コンテンツを文字列として提供します。 35 $innerHtml = $element->innerHTML; 36 37 echo "--- 元の HTML コンテンツスニペット ---" . PHP_EOL; 38 echo $htmlContent . PHP_EOL . PHP_EOL; 39 40 echo "--- ID 'container' の innerHTML ---" . PHP_EOL; 41 echo $innerHtml . PHP_EOL . PHP_EOL; 42 43 // 別の要素の innerHTML を取得する例 44 $simpleTextElement = $dom->getElementById('simpleTextElement'); 45 if ($simpleTextElement instanceof Element) { 46 echo "--- ID 'simpleTextElement' の innerHTML ---" . PHP_EOL; 47 echo $simpleTextElement->innerHTML . PHP_EOL; // "単純なテキスト" が出力されます 48 } 49 } else { 50 echo "エラー: ID 'container' を持つ Dom\Element が見つかりませんでした。" . PHP_EOL; 51 } 52} 53 54// サンプル関数を実行します。 55getDomElementInnerHtmlExample(); 56 57?>
PHP 8で導入された新しいDom拡張のDom\Elementクラスが提供するinnerHTMLプロパティは、HTML要素の内部コンテンツを文字列として取得するために使用されます。このプロパティに引数は不要で、要素の開始タグと終了タグの間に含まれるHTML構造やテキストをそのまま文字列(string)として返します。
サンプルコードでは、まずDom\Documentクラスのインスタンスを作成し、HTML文字列をloadHtml()メソッドで解析してDOMツリーを構築します。次に、getElementById()メソッドを使って特定のIDを持つDom\Element(ここではIDが'container'のdiv要素)を取得します。
要素が正常に取得できた場合、そのDom\ElementインスタンスのinnerHTMLプロパティにアクセスすることで、該当要素の内部にある<p>こんにちは、<strong>世界</strong>!</p><span>これはテストです。</span>のようなHTMLコンテンツ全体を文字列として取得し、表示しています。また、simpleTextElementの例では、要素内の単純なテキスト「単純なテキスト」も同様に取得できることを示しています。このようにinnerHTMLを利用することで、Webページの一部分の構造やテキスト情報を簡単に抽出することが可能です。
PHP 8以降の新しいDom拡張を使用しているため、古いPHPバージョンでは動作しません。Dom\Element::innerHTMLプロパティは、対象のHTML要素内に含まれるHTMLコンテンツを文字列として返します。要素を検索する際は、getElementById()などがnullを返す可能性があるため、必ずif ($element instanceof Element)のように要素の存在を確認してからアクセスしてください。取得したinnerHTMLの文字列にはHTMLタグなどが含まれるため、これをそのままWebページに出力すると、クロスサイトスクリプティング(XSS)などのセキュリティ上の脆弱性につながる恐れがあります。そのため、利用する際は適切なサニタイズ処理を検討してください。また、innerHTMLはメソッドではなくプロパティであるため、括弧を付けて呼び出さないよう注意が必要です。
PHP DOMでinnerHTML相当を取得する
1<?php 2 3// PHP 8 Dom\ElementクラスのinnerHTMLに相当する機能を提供します。 4// Dom\Elementクラスには直接innerHTMLプロパティはありませんが、 5// JavaScriptのinnerHTMLプロパティと同様に、要素の内部コンテンツ(子ノード全て)を 6// HTML文字列として取得する機能は、PHPのDOM拡張で実現できます。 7 8/** 9 * 指定されたDom\Elementオブジェクトの内部HTMLコンテンツを取得します。 10 * 11 * これはJavaScriptの HTMLElement.innerHTML プロパティに相当する機能です。 12 * Dom\Elementオブジェクト自体にはinnerHTMLプロパティがないため、 13 * その子ノードを反復処理し、それぞれのHTML表現を結合することで実現します。 14 * 15 * @param Dom\Element $element HTMLコンテンツを取得する対象の要素。 16 * @return string 要素の内部コンテンツを表すHTML文字列。 17 */ 18function getInnerHTML(Dom\Element $element): string 19{ 20 $innerHTML = ''; 21 // 要素の子ノードをすべて反復処理します。 22 foreach ($element->childNodes as $childNode) { 23 // 各子ノードのHTML表現を親ドキュメントのsaveHTMLメソッドを使用して取得し、結合します。 24 // Dom\Node::ownerDocument は、そのノードが属するDom\Documentインスタンスを返します。 25 // Dom\Document::saveHTML() メソッドは、指定されたノードとその子孫をHTML文字列として返します。 26 $innerHTML .= $element->ownerDocument->saveHTML($childNode); 27 } 28 return $innerHTML; 29} 30 31// --- 単体で動作可能なサンプルコード --- 32 33// 1. 処理対象となるHTML文字列を準備します。 34$htmlContent = ' 35<!DOCTYPE html> 36<html> 37<head> 38 <title>PHP innerHTML Equivalent Example</title> 39</head> 40<body> 41 <div id="container"> 42 <h1>Hello, World!</h1> 43 <p>This is a <strong>paragraph</strong> with some <em>emphasized</em> text.</p> 44 <!-- これはコメントノードです --> 45 <ul> 46 <li>Item 1</li> 47 <li>Item 2</li> 48 </ul> 49 直接div内のテキストノードです。 50 </div> 51 <div id="another-container"> 52 <p>別のコンテナのコンテンツ。</p> 53 </div> 54</body> 55</html>'; 56 57// 2. Dom\Documentを作成し、HTMLをロードします。 58$document = new Dom\Document(); 59// HTMLのパースエラーを抑制するために、内部エラーハンドリングを有効にします。 60libxml_use_internal_errors(true); 61$document->loadHTML($htmlContent); 62// パースエラーメッセージをクリアします(必要な場合のみ)。 63libxml_clear_errors(); 64 65// 3. 特定のDom\Elementオブジェクトを取得します。 66// Dom\Document::getElementById は DOMElement を返しますが、 67// PHP 8の新しいDom拡張では自動的にDom\Elementにマッピングされます。 68$containerElement = $document->getElementById('container'); 69 70// 4. getInnerHTML関数を使用して、対象要素の内部HTMLコンテンツを取得し、表示します。 71if ($containerElement instanceof Dom\Element) { 72 echo "--- HTMLコンテンツの例 ---" . PHP_EOL; 73 echo htmlspecialchars($htmlContent) . PHP_EOL . PHP_EOL; 74 75 echo "--- '#container' 要素の抽出された innerHTML ---" . PHP_EOL; 76 $innerHTML = getInnerHTML($containerElement); 77 // ターミナルでの表示崩れを防ぐため、HTMLエンティティに変換して出力します。 78 echo htmlspecialchars($innerHTML) . PHP_EOL; 79 echo PHP_EOL; 80 81 // 参考として、タグを含まない純粋なテキストコンテンツも表示します。 82 // これはJavaScriptの textContent や innerText プロパティに相当します。 83 echo "--- '#container' 要素の textContent (タグは含まれません) ---" . PHP_EOL; 84 echo htmlspecialchars($containerElement->textContent) . PHP_EOL; 85} else { 86 echo "ID 'container' を持つ要素が見つかりませんでした。" . PHP_EOL; 87}
PHP 8のDOM拡張機能は、WebページのHTML構造をプログラムで操作するために利用されます。JavaScriptのHTMLElement.innerHTMLプロパティのように、HTML要素の内部コンテンツ(子ノード全て)をHTML文字列として直接取得するプロパティは、Dom\Elementクラスにはありません。しかし、本サンプルコードで提供するgetInnerHTML関数を使用することで、このinnerHTMLに相当する機能を実現できます。
getInnerHTML関数は、HTMLコンテンツを取得したい対象のDom\Elementオブジェクトを引数として受け取ります。関数内部では、指定された要素の全ての子ノードを繰り返し処理し、ownerDocument->saveHTML()メソッドを使って各子ノードのHTML表現を取得し、これらを結合していきます。最終的に、結合された内部HTMLコンテンツを表す文字列が戻り値として返されます。
サンプルコードでは、まず用意したHTML文字列をDom\Documentオブジェクトとして読み込みます。次に、getElementByIdメソッドを用いて特定のIDを持つDom\Elementオブジェクト(ここではcontainer要素)を取得します。そして、この取得した要素をgetInnerHTML関数に渡すことで、その内部にあるHTMLコンテンツ全体を文字列として抽出し、画面に出力しています。出力時にhtmlspecialcharsを使用しているのは、取得したHTML文字列を安全に表示するためです。このように、PHPのDOM拡張機能と組み合わせることで、HTML要素の内部コンテンツを柔軟に取得・操作することが可能になります。
PHPのDom\ElementにはJavaScriptのinnerHTMLプロパティは直接存在しません。サンプルコードの通り、要素の内部HTMLコンテンツを取得するには、子ノードを一つずつHTML化し、$element->ownerDocument->saveHTML($childNode)で結合する方法が一般的です。saveHTML()は親ドキュメントオブジェクトから呼び出す点に留意してください。また、Dom\Document::loadHTML()でHTMLを読み込む際、パースエラーを抑制するためにlibxml_use_internal_errors(true)の設定と、エラークリアが有効です。取得したHTML文字列を画面に出力する際は、セキュリティのためにhtmlspecialchars()などでエスケープ処理を行うことを推奨します。タグを含まないテキストのみが必要な場合は、textContentプロパティを利用してください。