【PHP8.x】Dom\HTMLDocument::ownerDocumentプロパティの使い方
ownerDocumentプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
ownerDocumentプロパティは、ノードが属するドキュメントオブジェクトを保持するプロパティです。このプロパティはDom\Nodeインターフェースで定義されており、Dom\HTMLDocumentクラスもこれを継承しています。HTMLドキュメント内の特定の要素、例えば<body>や<p>といったノードからこのプロパティにアクセスすると、そのノードが所属しているDom\HTMLDocumentオブジェクトそのものが返されます。これにより、ドキュメントツリーのどの位置にいるノードからでも、ドキュメント全体を簡単に参照することが可能になります。しかし、Dom\HTMLDocumentオブジェクト自身、つまりドキュメントのルートノードに対してこのプロパティを参照した場合の動作は異なります。ドキュメント自体は他のいかなるドキュメントにも属していないため、この場合のプロパティの値は常にnullとなります。このプロパティは読み取り専用であり、プログラム中で値を代入して変更することはできません。
構文(syntax)
1<?php 2 3$document = new Dom\HTMLDocument(); 4$document->loadHTML('<!DOCTYPE html><html><body></body></html>'); 5 6$ownerDocument = $document->ownerDocument; 7 8var_dump($ownerDocument); 9 10?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
?Dom\Document
このプロパティは、その要素が属する Dom\Document オブジェクトへの参照を返します。要素がドキュメントに属していない場合は null を返します。
サンプルコード
ownerDocumentでドキュメントを操作しsaveHTMLする
1<?php 2 3/** 4 * Dom\HTMLDocumentのownerDocumentプロパティとsaveHTMLメソッドの使用例を示します。 5 * 6 * この関数は、HTMLドキュメントを作成し、その中の要素のownerDocumentプロパティを通じて 7 * 元のドキュメントにアクセスし、最後にそのドキュメントのHTMLコンテンツを抽出します。 8 * ownerDocumentがnullになるケース(ドキュメント自身のownerDocument)についても言及します。 9 */ 10function demonstrateOwnerDocumentAndSaveHTML(): void 11{ 12 // 1. 新しい Dom\HTMLDocument オブジェクトを作成します。 13 // Dom\HTMLDocumentはHTMLコンテンツを扱うためのDOMドキュメントオブジェクトです。 14 $htmlDocument = new Dom\HTMLDocument(); 15 16 // 2. HTMLコンテンツをドキュメントにロードします。 17 // loadHTML()は文字列からHTMLをパースし、DOMツリーを構築します。 18 $htmlContent = '<!DOCTYPE html><html><head><title>サンプルドキュメント</title></head><body><h1>こんにちは</h1><p id="intro">これは簡単なHTMLドキュメントです。</p></body></html>'; 19 $htmlDocument->loadHTML($htmlContent); 20 21 echo "--- ドキュメントがロードされました ---\n\n"; 22 23 // 3. ドキュメント内の特定の要素(ノード)を見つけます。 24 // getElementById()は、指定されたIDを持つ最初の要素を返します。 25 $paragraphElement = $htmlDocument->getElementById('intro'); 26 27 if ($paragraphElement === null) { 28 echo "エラー: 指定されたID 'intro' の段落要素が見つかりませんでした。\n"; 29 return; 30 } 31 32 echo "見つかった要素: " . $paragraphElement->nodeName . " (ID: " . $paragraphElement->getAttribute('id') . ")\n\n"; 33 34 // 4. 見つかった要素の ownerDocument プロパティにアクセスします。 35 // ドキュメント内のノードのownerDocumentは、そのノードが属するDom\Documentオブジェクトです。 36 // この場合、Dom\HTMLDocumentインスタンスである $htmlDocument が返されます。 37 $ownerDocOfParagraph = $paragraphElement->ownerDocument; 38 39 // 5. ownerDocumentが期待通り Dom\Document インスタンスであることを確認します。 40 // ownerDocumentプロパティは、null または Dom\Document オブジェクトを返します。 41 if ($ownerDocOfParagraph instanceof Dom\Document) { 42 echo "段落要素の ownerDocument は " . get_class($ownerDocOfParagraph) . " です。\n"; 43 echo "これは、元の Dom\\HTMLDocument オブジェクトと同じインスタンスです: " . ($ownerDocOfParagraph === $htmlDocument ? "はい" : "いいえ") . "\n\n"; 44 45 // 6. ownerDocument (つまり元の $htmlDocument) に対して saveHTML() を使用し、 46 // ドキュメント全体のHTMLコンテンツを文字列として取得します。 47 echo "--- ownerDocument から取得したHTMLコンテンツ (saveHTML() を使用) ---\n"; 48 echo $ownerDocOfParagraph->saveHTML(); 49 echo "\n------------------------------------------------------------\n\n"; 50 51 // 参考: 特定のノードに対して saveHTML() を使用すると、そのノードと子孫のHTMLのみが取得されます。 52 echo "--- 段落要素自身から取得したHTMLコンテンツ (saveHTML() を使用) ---\n"; 53 echo $paragraphElement->saveHTML(); 54 echo "\n-----------------------------------------------------------\n"; 55 56 } else { 57 echo "エラー: 段落要素の ownerDocument が Dom\\Document インスタンスではありませんでした。\n"; 58 } 59 60 // 7. Dom\HTMLDocument オブジェクト自身の ownerDocument プロパティを調べます。 61 // DOMの仕様により、Documentオブジェクト自身のownerDocumentはnullになります。 62 echo "\n--- Dom\\HTMLDocument オブジェクト自身の ownerDocument ---\n"; 63 if ($htmlDocument->ownerDocument === null) { 64 echo "Dom\\HTMLDocument オブジェクトの ownerDocument は null です。これは、自身がドキュメントであるためです。\n"; 65 } else { 66 echo "予期せぬ結果: Dom\\HTMLDocument オブジェクトの ownerDocument が null ではありませんでした。\n"; 67 } 68 echo "------------------------------------------------------------------\n"; 69} 70 71// 関数を実行してデモンストレーションを開始します。 72demonstrateOwnerDocumentAndSaveHTML();
PHPのDom\HTMLDocumentクラスは、HTMLコンテンツをプログラムで操作するためのDOM(Document Object Model)ドキュメントオブジェクトです。このクラスは、HTML構造をツリー状に表現し、要素や属性などを扱えるようにします。
ownerDocumentプロパティは、DOMツリー内の個々の要素(ノード)がどのDom\Documentオブジェクトに属しているかを示す重要なプロパティです。例えば、HTMLドキュメント内の特定の段落要素を取得した場合、その段落要素のownerDocumentプロパティにアクセスすると、その段落要素を作成した、または読み込まれた元のDom\HTMLDocumentインスタンスがDom\Document型として返されます。これにより、要素から元のドキュメント全体に簡単にアクセスし、他の操作を続けることが可能になります。一方で、Dom\HTMLDocumentオブジェクト自身がドキュメントであるため、自身のownerDocumentプロパティにアクセスするとnullが返されます。
saveHTML()メソッドは、Dom\Documentオブジェクトや特定のDOMノードの現在のHTML表現を文字列として取得するために使用されます。このメソッドに引数はありません。Dom\Documentオブジェクトに対してsaveHTML()を実行すると、ドキュメント全体のHTMLコンテンツが返されます。また、特定の要素(例:段落要素)に対してsaveHTML()を実行すると、その要素とそれに含まれるすべての子要素のHTMLコンテンツのみが返されます。サンプルコードでは、HTMLドキュメントをロードし、特定の要素からownerDocumentを通じて元のドキュメントにアクセスし、そのドキュメントに対してsaveHTML()を使ってHTMLコンテンツ全体を抽出する流れが示されています。
ownerDocumentプロパティは、HTML要素がどのドキュメントに属しているかを示すものです。HTMLドキュメントそのもののownerDocumentは常にnullとなるため、この点を理解しておくことが重要です。それ以外の要素の場合、その要素が属するDom\Documentオブジェクトが返されます。ownerDocumentの戻り値はnullの可能性があるため、プロパティにアクセスする前には必ずnullチェックや型チェックを行い、安全に利用してください。また、saveHTML()メソッドは、ドキュメント全体から呼び出すか、特定の要素から呼び出すかによって、取得できるHTMLの範囲が異なります。ドキュメント全体のHTMLが必要な場合はDom\HTMLDocumentオブジェクトから、特定の部分のみのHTMLが必要な場合はその要素から呼び出すようにしてください。
HTML要素のownerDocumentを取得する
1<?php 2 3/** 4 * Dom\HTMLDocument を用いた ownerDocument プロパティの使用例。 5 * 6 * この関数は、HTMLドキュメントを作成し、その中の要素がどのドキュメントに属しているかを 7 * `ownerDocument` プロパティを通じて確認する方法を示します。 8 * システムエンジニアを目指す初心者向けに、DOMツリーの基本と、 9 * 各ノードが所属するドキュメントオブジェクトへの参照方法を解説します。 10 */ 11function demonstrateOwnerDocumentProperty(): void 12{ 13 // 1. 新しい HTML ドキュメントを作成します。 14 // Dom\HTMLDocument は HTML ドキュメントを扱うための特別な Dom\Document クラスです。 15 // このクラスのインスタンス自体は、DOMツリーの「根」となるドキュメントオブジェクトであり、 16 // それ自身がownerDocumentプロパティを持つノードではありません。 17 $htmlDocument = new Dom\HTMLDocument('1.0', 'UTF-8'); 18 echo "1. 新しい Dom\\HTMLDocument オブジェクトを作成しました。\n"; 19 echo " ドキュメントのタイプ: " . get_class($htmlDocument) . "\n\n"; 20 21 // 2. ドキュメントに HTML 要素を追加します。 22 // DOM操作の基本として、まずルート要素となる <html> 要素を作成し、ドキュメントに追加します。 23 $htmlElement = $htmlDocument->createElement('html'); 24 $htmlDocument->appendChild($htmlElement); 25 26 // 次に、<body> 要素を作成し、<html> の子要素として追加します。 27 $bodyElement = $htmlDocument->createElement('body'); 28 $htmlElement->appendChild($bodyElement); 29 30 // <body> 要素内に <p> 要素を作成し、テキストノードを追加します。 31 // <p> 要素は Dom\Element クラスのインスタンスであり、Dom\Node を継承しています。 32 // `ownerDocument` プロパティはこの Dom\Node クラスに定義されています。 33 $paragraphElement = $htmlDocument->createElement('p', 'これはサンプル段落です。'); 34 $bodyElement->appendChild($paragraphElement); 35 36 echo "2. HTML ドキュメント内に要素 (<p>) を作成し、追加しました。\n"; 37 echo " 追加した要素: <" . $paragraphElement->tagName . ">" . $paragraphElement->textContent . "</" . $paragraphElement->tagName . ">\n\n"; 38 39 // 3. 追加した <p> 要素の ownerDocument プロパティにアクセスします。 40 // `ownerDocument` プロパティは、Dom\Node を継承するすべてのノード(要素、テキスト、コメントなど)が持ち、 41 // そのノードが属する Dom\Document オブジェクトを返します。 42 // これは、要素がどのドキュメントツリーの一部であるかを知るために非常に役立ちます。 43 $ownerDocOfParagraph = $paragraphElement->ownerDocument; 44 45 echo "3. 作成した <p> 要素の ownerDocument プロパティを参照します。\n"; 46 echo " ownerDocument の型: " . (is_object($ownerDocOfParagraph) ? get_class($ownerDocOfParagraph) : 'null') . "\n"; 47 48 // 4. `ownerDocument` が元の HTMLDocument オブジェクトと同一であることを確認します。 49 // `===` 演算子を使って、オブジェクトがメモリ上で同一であるかをチェックします。 50 // これにより、取得した ownerDocument が、まさにこの要素を作成したドキュメント自身であることが確認できます。 51 if ($ownerDocOfParagraph instanceof Dom\Document && $ownerDocOfParagraph === $htmlDocument) { 52 echo " 確認: <p> 要素の ownerDocument は、元の Dom\\HTMLDocument オブジェクトと同一です。\n"; 53 } else { 54 echo " 確認: <p> 要素の ownerDocument は、元の Dom\\HTMLDocument と同一ではありません。(予期せぬ結果)\n"; 55 } 56 echo "\n"; 57 58 // 補足: ownerDocument の戻り値が `?Dom\Document` であることについて。 59 // `?` は null 許容型を意味し、戻り値が Dom\Document オブジェクトまたは null の可能性があることを示します。 60 // 例えば、まだどのドキュメントにも追加されていない「孤立した」ノードの場合、 61 // ownerDocument は null を返すことがあります。 62 // しかし、今回のように既にドキュメントに所属しているノードの場合、必ず Dom\Document オブジェクトを返します。 63 echo "補足: ownerDocument プロパティの戻り値は `?Dom\\Document` (null 許容型) です。\n"; 64 echo "これは、場合によっては null を返す可能性があることを意味します。\n"; 65 echo "しかし、今回のようにドキュメントに所属しているノードの場合、必ず Dom\\Document オブジェクトを返します。\n"; 66} 67 68// 関数の実行 69demonstrateOwnerDocumentProperty(); 70 71?>
PHPのDom拡張機能におけるownerDocumentプロパティは、DOMツリー内のノード(要素、テキストなど)が、どのDom\Documentオブジェクトに所属しているかを示すプロパティです。このサンプルコードでは、まず新しいDom\HTMLDocumentを作成し、その中に<p>要素などのHTML要素を順に追加しています。その後、追加された<p>要素からownerDocumentプロパティにアクセスし、そのノードが属するドキュメントオブジェクトを取得しています。
ownerDocumentプロパティは引数を取らず、戻り値は?Dom\Document型です。これは、Dom\Documentオブジェクトまたはnullのいずれかを返すことを示します。ノードが既にDOMツリーの一部としてドキュメントに所属している場合、そのノードのルートであるDom\Documentオブジェクトを返します。しかし、もしノードがまだどのドキュメントにも追加されていない「孤立した」状態であれば、nullを返します。今回のサンプルコードでは、<p>要素は作成したDom\HTMLDocumentに追加されているため、ownerDocumentプロパティは元のDom\HTMLDocumentオブジェクトを返します。コードでは、この返されたオブジェクトが元のドキュメントと同一であることを検証しています。このプロパティは、特に複数のドキュメントを扱う際や、ノードのコンテキスト情報を確認したい場合に役立ち、DOMツリーの構造を理解する上で重要な役割を果たします。
ownerDocumentプロパティは、Dom\ElementなどのDom\Nodeを継承する各ノードが、どのDom\Documentオブジェクトに属しているかを示すものです。Dom\HTMLDocumentのようなドキュメントオブジェクト自身はDOMツリーの根であり、このプロパティを持ちません。戻り値は?Dom\Documentと定義されているため、ノードがまだどのドキュメントにも追加されていない「孤立した」状態の場合にはnullを返す可能性があります。したがって、ownerDocumentプロパティを利用する際は、nullが返される可能性を考慮し、適切にハンドリングすることが重要です。また、取得したownerDocumentが意図したドキュメントと同一であるかを確認する際には、オブジェクトの同一性をチェックする===演算子を利用するのが確実です。