【PHP8.x】DOMNode::baseURIプロパティの使い方
baseURIプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『baseURIプロパティは、そのノードのベースURI(Base Uniform Resource Identifier)を保持する読み取り専用のプロパティです。ベースURIとは、文書内で使用されている相対パス(例: images/photo.jpg)を、完全なURL(例: https://example.com/path/images/photo.jpg)に変換するための基準となるURIを指します。HTML文書やXML文書を扱う際、画像やリンクなどのリソースが相対パスで記述されていることはよくあります。このプロパティを使用することで、各ノードがどのURIを基準にしているかをプログラムで正確に把握でき、相対的なリンクを絶対的なリンクへ解決する処理などに役立ちます。ベースURIは、通常、文書が読み込まれた場所のURIや、HTMLの<base>タグ、XMLのxml:base属性によって決定されます。もし文書がファイルやURLから読み込まれておらず、メモリ上で動的に生成された場合など、基準となるURIが不明な状況では、このプロパティはnullを返します。このプロパティは読み取り専用であるため、baseURIに直接値を代入して変更することはできません。』
構文(syntax)
1<?php 2 3$html = <<<HTML 4<!DOCTYPE html> 5<html> 6<head> 7 <title>Example</title> 8</head> 9<body> 10 <p id="paragraph">This is a paragraph.</p> 11</body> 12</html> 13HTML; 14 15$doc = new DOMDocument(); 16 17// ドキュメントのURIを設定します。これが基底URIの基準となります。 18$doc->documentURI = 'http://www.example.com/path/page.html'; 19$doc->loadHTML($html); 20 21$node = $doc->getElementById('paragraph'); 22 23// DOMNodeの baseURI プロパティにアクセスして、ノードの基底URIを取得します。 24echo $node->baseURI; 25 26?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMNodeオブジェクトが属するドキュメントのベースURIを文字列で返します。ドキュメントにベースURIが定義されていない場合はnullを返します。
サンプルコード
PHP DOMNode::baseURIでベースURIを取得する
1<?php 2 3/** 4 * DOMNode::baseURI プロパティのサンプルコード 5 * 6 * このコードは、DOMノードのベースURIがどのように決定され、取得されるかを示します。 7 * ベースURIは、ドキュメントがロードされた元のURIや、HTMLの<base>タグに影響されます。 8 * 9 * システムエンジニアを目指す初心者の方へ: 10 * baseURIは、HTMLやXMLドキュメント内の相対パスを絶対パスに解決する際の基準となるURIです。 11 * たとえば、<img src="image.png"> のようなパスがあった場合、 12 * この "image.png" が実際にどこにあるファイルを指すのかを決定するためにbaseURIが使用されます。 13 * ドキュメント全体または特定のノードが「どのURIのコンテキストで存在しているか」を示します。 14 */ 15function getDomNodeBaseURIExample(): void 16{ 17 // 例1: DOMDocument::documentURI を設定してベースURIを確認する 18 // この場合、メモリ上のHTMLに仮想的なURIを設定します。 19 $dom1 = new DOMDocument(); 20 $dom1->documentURI = 'http://www.example.com/articles/index.html'; 21 22 // <base>タグを含まない簡単なHTML文字列をロード 23 $htmlString1 = '<!DOCTYPE html><html><head><title>Article</title></head><body><p>Hello PHP!</p></body></html>'; 24 $dom1->loadHTML($htmlString1); 25 26 // DOMDocumentオブジェクト自体もDOMNodeを継承しているため、そのbaseURIプロパティにアクセスできます。 27 // documentURIが設定されている場合、それがベースURIとして使用されます。 28 echo "--- 例1: documentURI を設定した場合 ---\n"; 29 echo "DOMDocumentノードの baseURI: " . ($dom1->baseURI ?? 'NULL') . "\n\n"; 30 31 // 例2: <base>タグを含むHTMLをロードしてベースURIを確認する 32 // HTMLドキュメント内に<base>タグが存在する場合、そのhref属性がベースURIとして優先されます。 33 $dom2 = new DOMDocument(); 34 $htmlString2 = <<<HTML 35 <!DOCTYPE html> 36 <html> 37 <head> 38 <base href="http://cdn.example.com/assets/"> 39 <title>Media Gallery</title> 40 </head> 41 <body> 42 <img src="photos/image.jpg" alt="Gallery Image"> 43 </body> 44 </html> 45 HTML; 46 47 $dom2->loadHTML($htmlString2); 48 49 // <base>タグのhref属性が、ドキュメント全体のベースURIとして取得されます。 50 echo "--- 例2: <base>タグが存在する場合 ---\n"; 51 echo "DOMDocumentノードの baseURI: " . ($dom2->baseURI ?? 'NULL') . "\n"; 52 53 // 他の要素(<body>や<img>)のbaseURIも確認してみます。 54 // 通常、ドキュメント内のすべてのノードは同じベースURIを持ちます。 55 $bodyNode = $dom2->getElementsByTagName('body')->item(0); 56 if ($bodyNode instanceof DOMNode) { 57 echo "<body>ノードの baseURI: " . ($bodyNode->baseURI ?? 'NULL') . "\n"; 58 } 59 60 $imgNode = $dom2->getElementsByTagName('img')->item(0); 61 if ($imgNode instanceof DOMNode) { 62 echo "<img>ノードの baseURI: " . ($imgNode->baseURI ?? 'NULL') . "\n"; 63 } 64} 65 66// サンプル関数を実行 67getDomNodeBaseURIExample();
DOMNode::baseURIプロパティは、PHPでDOM (Document Object Model) を扱う際に、各ノードに関連付けられたベースURIを取得するために使用されます。ベースURIとは、HTMLやXMLドキュメント内で指定された相対パス(例: <img src="image.png">)を、絶対パスとして解決する際の基準となるURIのことです。これは、ドキュメントがどこからロードされたか、またはHTMLの<base>タグのhref属性によって決定される場合があります。このプロパティは引数を取らず、戻り値としてベースURIをstring型で返します。もしベースURIが決定できない場合はnullを返します。
このサンプルコードは、baseURIプロパティがどのように機能するかを具体的な例で示しています。最初の例では、DOMDocumentオブジェクトのdocumentURIプロパティにURIを明示的に設定することで、メモリ上で作成されたHTMLコンテンツにも仮想的なベースURIが付与され、それがDOMDocumentノードのbaseURIとして取得されることを確認しています。次の例では、HTMLドキュメント内に<base>タグを配置した場合、そのhref属性の値がドキュメント全体のベースURIとして優先されることを示しています。さらに、ドキュメント内の<body>や<img>といった子要素も、通常はドキュメント全体のベースURIと同じ値を返すことが確認でき、HTMLコンテンツ内の相対的なリソースパスがどのURIを基準として解決されるかを理解できます。
DOMNode::baseURIプロパティは、HTMLやXMLドキュメント内の相対パスを絶対パスに解決する際の基準となるURIを返します。このURIは、DOMDocument::documentURIプロパティの設定や、HTMLの<base>タグのhref属性によって決定されます。特に<base>タグが存在する場合は、その値が優先されることを覚えておきましょう。プロパティの戻り値はstring型またはnullであるため、nullが返される可能性を考慮し、常に存在すると仮定せずにnullチェックを行うか、Null合体演算子などを用いて安全に扱うことが重要です。ドキュメント内のほとんどのノードは同じbaseURIを持ちますが、その値が何に影響されているのかを理解することが、パス解決のデバッグや挙動の予測に役立ちます。
PHP DOMNode baseURIでドキュメントのベースURIを取得する
1<?php 2 3/** 4 * 与えられたHTMLコンテンツから、ドキュメントのベースURIを取得します。 5 * 6 * DOMNode::baseURI プロパティは、そのノードが属するドキュメントのベースURIを返します。 7 * これはHTMLドキュメント内の相対URLを解決するための基準となるURLです。 8 * 特に、HTMLの <base> 要素が指定されている場合にその値が使用されます。 9 * 10 * @param string $htmlContent 解析するHTML文字列。 11 * @return string|null ドキュメントのベースURI、または指定がない場合はnull。 12 */ 13function getDocumentBaseUri(string $htmlContent): ?string 14{ 15 // DOMDocument オブジェクトを作成します。 16 // これを使ってHTMLやXMLを解析し、DOMツリーとして扱います。 17 $dom = new DOMDocument(); 18 19 // HTMLをロードする際に出る可能性のある警告やエラーを抑制します。 20 // libxml_use_internal_errors(true) は、エラーをPHPのエラーハンドラではなく、 21 // libxmlの内部エラーキューに格納するようにします。 22 libxml_use_internal_errors(true); 23 24 // HTML文字列をDOMDocumentにロードします。 25 $dom->loadHTML($htmlContent); 26 27 // 内部エラーキューに格納されたエラーをクリアします。 28 // これにより、後続の処理で以前のエラーが影響するのを防ぎます。 29 libxml_clear_errors(); 30 31 // DOMDocument オブジェクト(DOMNodeを継承)の baseURI プロパティにアクセスします。 32 // このプロパティは、ドキュメントのベースURIを返します。 33 // - HTMLに <base href="..."> タグが存在する場合、その href 属性の値が返されます。 34 // - <base> タグが存在しない、または文書がメモリ上の文字列からロードされた場合、 35 // 通常は null が返されます(ファイルからロードされた場合はファイルパス)。 36 return $dom->baseURI; 37} 38 39// --- サンプルコードの実行 --- 40 41echo "=== DOMNode::baseURI の使用例 ===\n\n"; 42 43// 例1: <base> 要素がないHTMLコンテンツ 44// ドキュメントのベースURIは明示的に指定されていないため、nullが返されます。 45$htmlWithoutBase = '<!DOCTYPE html> 46<html> 47<head><title>No Base URI Example</title></head> 48<body> 49 <h1>Hello World</h1> 50 <p>このドキュメントには <base> 要素がありません。</p> 51</body> 52</html>'; 53 54$baseUri1 = getDocumentBaseUri($htmlWithoutBase); 55echo "HTML (base要素なし):\n"; 56echo " ベースURI: " . ($baseUri1 ?? 'null (ベースURIが明示されていません)') . "\n\n"; 57 58// 例2: <base> 要素があるHTMLコンテンツ 59// <base href="..."> に指定されたURIがベースURIとして返されます。 60$htmlWithBase = '<!DOCTYPE html> 61<html> 62<head> 63 <base href="http://www.example.com/docs/latest/"> 64 <title>With Base URI Example</title> 65</head> 66<body> 67 <h1>Welcome</h1> 68 <a href="images/logo.png">ロゴ画像</a> (この相対パスは上記ベースURIで解決されます) 69</body> 70</html>'; 71 72$baseUri2 = getDocumentBaseUri($htmlWithBase); 73echo "HTML (base要素あり):\n"; 74echo " ベースURI: " . ($baseUri2 ?? 'null') . "\n\n"; 75 76// 例3: 相対パスの <base> 要素があるHTMLコンテンツ 77// <base href="..."> に指定された相対URIがそのままベースURIとして返されます。 78// ドキュメントがメモリからロードされているため、この相対URIは絶対URIに解決されません。 79$htmlWithRelativeBase = '<!DOCTYPE html> 80<html> 81<head> 82 <base href="/assets/static/"> 83 <title>With Relative Base URI Example</title> 84</head> 85<body> 86 <h1>Relative Base</h1> 87 <a href="css/style.css">スタイルシート</a> (このパスもbaseで指定されたパスが基準になります) 88</body> 89</html>'; 90 91$baseUri3 = getDocumentBaseUri($htmlWithRelativeBase); 92echo "HTML (相対パスのbase要素あり):\n"; 93echo " ベースURI: " . ($baseUri3 ?? 'null') . "\n\n"; 94 95?>
PHP 8のDOMNode::baseURIプロパティは、HTMLドキュメント内の相対URLを解決する基準となるベースURIを取得するために使用されます。このプロパティは、そのノードが属するドキュメント、特にHTMLコンテンツの<base>要素に指定されたURIを返します。サンプルコードでは、与えられたHTMLコンテンツからこのベースURIを抽出するgetDocumentBaseUri関数を提供しています。
getDocumentBaseUri関数は、解析対象のHTMLコンテンツを文字列として$htmlContent引数に受け取ります。関数内部では、DOMDocumentオブジェクトを使用してHTMLを解析し、そのドキュメントのbaseURIプロパティにアクセスします。戻り値は、ドキュメントに<base>要素が存在し、そのhref属性が設定されている場合はそのURIをstringとして返し、存在しない場合や明示的なベースURIがない場合はnullを返します。
具体例として、サンプルコードでは3つのケースを示しています。まず、<base>要素を含まないHTMLからはnullが返されることを確認できます。次に、<base href="http://www.example.com/">のように絶対パスが指定されたHTMLからは、その絶対パスがベースURIとして返されます。さらに、<base href="/assets/">のような相対パスが指定された場合も、その相対パスがそのままベースURIとして取得されます。このように、baseURIプロパティを使用することで、HTMLドキュメントがどのように相対パスを解決するかの基準を簡単に確認でき、ウェブコンテンツの解析やリンク解決時に役立ちます。
DOMNode::baseURIプロパティは、HTMLドキュメント内の相対URLを解決するための基準となるURLを取得します。最も重要な注意点は、HTMLに<base>タグが存在しない場合や、ドキュメントがメモリからロードされた場合はnullが返される可能性が高いことです。そのため、取得した値がnullでないかを常に確認し、適切に処理するコードを記述してください。
このプロパティは、HTMLの<base href="...">タグに指定されたURLを優先的に返します。サンプルコードでは、HTML解析時に発生しうる警告やエラーを抑制するためにlibxml_use_internal_errors関数を使用し、その後のlibxml_clear_errorsでエラーをクリアしています。これは、堅牢なアプリケーションを作成する上で、DOM操作におけるエラー処理のベストプラクティスの一つとして参考にしてください。