【PHP8.x】DOMEntityReference::baseURIプロパティの使い方
baseURIプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『baseURIプロパティは、エンティティ参照ノードの絶対基底URIを保持するプロパティです』
このプロパティは読み取り専用であり、そのノードが属するドキュメントの基となるURIを文字列で返します。基底URIとは、ドキュメント内で相対パス(例: ../images/pic.png)を解釈する際の基準となる絶対パス(例: http://example.com/docs/)のことです。この値は、ドキュメントがどこから読み込まれたかによって自動的に決定されます。例えば、DOMDocument::loadHTMLFile() を使って特定のURLからドキュメントを読み込んだ場合、そのURLが基底URIとなります。もしドキュメントがファイルやネットワークからではなく、文字列から直接生成された場合(例: DOMDocument::loadXML())や、実装が基底URIを特定できなかった場合には、このプロパティの値は null になります。ドキュメント内のリソースへのパスを絶対パスに変換する際などに利用されます。このプロパティは DOMNode クラスから継承されています。
構文(syntax)
1<?php 2// サンプル用のXMLファイルを作成 3$xmlString = <<<XML 4<?xml version="1.0" encoding="UTF-8"?> 5<!DOCTYPE root [ 6 <!ENTITY example "This is an entity."> 7]> 8<root>&example;</root> 9XML; 10file_put_contents('sample.xml', $xmlString); 11 12// DOMDocumentオブジェクトを作成し、XMLファイルを読み込む 13$doc = new DOMDocument(); 14$doc->load('sample.xml'); 15 16// root要素の最初の子ノードであるエンティティ参照ノードを取得 17$entityRef = $doc->documentElement->firstChild; 18 19// DOMEntityReferenceオブジェクトのbaseURIプロパティにアクセスして値を取得 20// このプロパティは、ノードがどのドキュメントから来たかを示すURIを保持します 21$uri = $entityRef->baseURI; 22 23// 取得したURIを出力(例: file:///path/to/your/script/sample.xml) 24var_dump($uri); 25 26// 作成したファイルを削除 27unlink('sample.xml'); 28?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMEntityReference オブジェクトが参照するエンティティの基底 URI を文字列で返します。エンティティの URI が不明な場合は null を返します。
サンプルコード
PHP DOMEntityReference baseURI を取得する
1<?php 2 3/** 4 * DOMEntityReference クラスの baseURI プロパティの取得方法を示すサンプル関数。 5 * 6 * この関数は、DTDで定義されたカスタムエンティティを含むXML文字列をパースし、 7 * DOMツリーから DOMEntityReference ノードを見つけ、その baseURI プロパティを 8 * 表示します。 9 * 10 * baseURI はノードが読み込まれたURIを示しますが、この例のようにメモリ上の 11 * 文字列からXMLがパースされた場合、通常は null になります。 12 * ファイルからXMLを読み込んだ場合は、そのファイルのパスがURIとして返される 13 * ことがあります。 14 * 15 * @return void 16 */ 17function demonstrateDomEntityReferenceBaseURI(): void 18{ 19 // 1. DOMDocument オブジェクトを作成します。 20 $dom = new DOMDocument(); 21 22 // 2. エンティティ参照を実体化せずにノードとして残す設定を行います。 23 // これにより、XML文書中の &entityName; の部分が DOMEntityReference ノードとして扱われます。 24 // この設定は、DTDを読み込む場合に特に重要です。 25 $dom->substituteEntities = false; 26 27 // 3. カスタムエンティティをDTDで定義し、それを参照するXML文字列を用意します。 28 // <!ENTITY customEntity ... > でエンティティを定義し、 29 // &customEntity; でそのエンティティを参照しています。 30 $xmlString = <<<XML 31 <!DOCTYPE root [ 32 <!ENTITY customEntity "This is a custom entity definition."> 33 ]> 34 <root> 35 <paragraph>&customEntity;</paragraph> 36 <paragraph>&</paragraph> <!-- 組み込みエンティティ (&) は通常DOMEntityReferenceになりません --> 37 </root> 38 XML; 39 40 // 4. XML文字列をDOMDocumentにロードします。 41 // LIBXML_DTDLOAD は、XML文書内のDTD(Document Type Definition)を読み込むことを指示します。 42 // これにより、上記で定義した <!ENTITY ... > が認識されます。 43 $dom->loadXML($xmlString, LIBXML_DTDLOAD); 44 45 // 5. DOMツリーを走査し、DOMEntityReference ノードを探します。 46 // XML_ENTITY_REF_NODE は、PHPのDOM拡張におけるエンティティ参照ノードのタイプを示す定数です (値は 6)。 47 $foundEntityReference = false; 48 foreach ($dom->getElementsByTagName('paragraph') as $element) { 49 foreach ($element->childNodes as $childNode) { 50 if ($childNode->nodeType === XML_ENTITY_REF_NODE) { 51 /** @var DOMEntityReference $childNode */ // 型ヒント 52 echo "--- DOMEntityReference ノードが見つかりました ---\n"; 53 echo "ノード名 (エンティティ名): " . $childNode->nodeName . "\n"; 54 echo "baseURI プロパティ: " . ($childNode->baseURI ?? 'null') . "\n"; 55 echo "補足: この例ではXMLがメモリ上の文字列からパースされたため、baseURIは 'null' となっています。\n"; 56 echo " もしファイルからXMLが読み込まれていれば、そのファイルのパスが返される可能性があります。\n"; 57 $foundEntityReference = true; 58 } 59 } 60 } 61 62 if (!$foundEntityReference) { 63 echo "DOMEntityReference ノードは見つかりませんでした。\n"; 64 echo "これは、エンティティが自動的に実体化されてしまったか、\n"; 65 echo "XML構造に問題がある可能性があります。\n"; 66 } 67} 68 69// サンプル関数を実行します。 70demonstrateDomEntityReferenceBaseURI(); 71
PHPのDOMEntityReferenceクラスが持つbaseURIプロパティは、エンティティ参照ノードが読み込まれた際のURI(Uniform Resource Identifier)を示すプロパティです。このプロパティは引数を取りません。戻り値はstring型、またはURIが特定できない場合はnullとなります。
サンプルコードでは、DTDでカスタムエンティティを定義し、それを参照するXML文字列をメモリ上でパースする例を示しています。DOMDocumentオブジェクトのsubstituteEntitiesプロパティをfalseに設定し、loadXMLメソッドにLIBXML_DTDLOADオプションを渡すことで、XML内のエンティティ参照(&customEntity;など)がDOMEntityReferenceノードとしてDOMツリーに保持されるようにしています。
その後、DOMツリーを走査してDOMEntityReferenceノードを探し、そのbaseURIプロパティの値を出力しています。この例のようにXMLがメモリ上の文字列から読み込まれた場合、ノードの基盤となるURIが存在しないため、baseURIプロパティはnullを返します。しかし、もしXMLファイルから読み込まれた場合は、そのファイルのパスがURIとして返されることがあります。baseURIプロパティは、XML文書のどこからコンテンツが読み込まれたかという、ソースに関する情報を提供する際に利用できます。
DOMEntityReference::baseURIプロパティは、XMLがメモリ上の文字列からロードされた場合、通常nullを返します。ファイルからXMLを読み込んだ際に、そのファイルのパスが返される可能性があるため、常にURIが取得できるとは限らない点にご注意ください。DOMEntityReferenceノードを正しく取得するためには、DOMDocumentのsubstituteEntitiesプロパティをfalseに設定し、loadXMLやloadHTMLメソッドでLIBXML_DTDLOADフラグを指定することが不可欠です。これらの設定を忘れると、エンティティが自動的に展開されてしまい、DOMEntityReferenceとして認識されません。また、&のような組み込みエンティティは通常DOMEntityReferenceノードにはならないことも理解しておきましょう。
DOMEntityReferenceのbaseURIを取得する
1<?php 2 3/** 4 * DOMEntityReference ノードの baseURI プロパティを取得するサンプルコード。 5 * 6 * この関数は、一時的なXMLファイルを作成し、DOMDocument でそのファイルを読み込みます。 7 * ドキュメント内に定義されたエンティティ参照ノード (DOMEntityReference) を探し、 8 * その baseURI プロパティの値を出力します。 9 * baseURI は、そのノードが属するドキュメントの絶対ベースURIを示します。 10 */ 11function getDomEntityReferenceBaseUri(): void 12{ 13 // 1. 一時的なXMLファイルを作成 14 // エンティティ参照「&appName;」を含むXMLコンテンツを定義します。 15 // このファイルは後で DOMDocument で読み込まれます。 16 $xmlFilePath = sys_get_temp_dir() . '/dom_entity_reference_example_' . uniqid() . '.xml'; 17 $xmlContent = <<<XML 18<?xml version="1.0" encoding="UTF-8"?> 19<!DOCTYPE root [ 20 <!-- 内部サブセットにエンティティ「appName」を定義 --> 21 <!ENTITY appName "My PHP Application"> 22]> 23<root> 24 <item> 25 開発元: &appName; 26 </item> 27</root> 28XML; 29 file_put_contents($xmlFilePath, $xmlContent); 30 31 // 2. DOMDocument オブジェクトを作成し、XMLファイルをロード 32 // load() メソッドを使用すると、そのファイルのパスがドキュメントのベースURIとなります。 33 $dom = new DOMDocument(); 34 $dom->load($xmlFilePath); 35 36 // 3. DOMツリーを走査し、DOMEntityReference ノードを探す 37 // DOMXPath を使用してすべての要素を検索し、その子ノードからノードの種類 (XML_ENTITY_REF_NODE) で判別します。 38 $entityRefNode = null; 39 $xpath = new DOMXPath($dom); 40 foreach ($xpath->query('//*') as $element) { 41 foreach ($element->childNodes as $childNode) { 42 // ノードの種類が XML_ENTITY_REF_NODE (7) であるかチェック 43 if ($childNode->nodeType === XML_ENTITY_REF_NODE) { 44 $entityRefNode = $childNode; 45 break 2; // DOMEntityReference が見つかったら、外側のループも抜ける 46 } 47 } 48 } 49 50 // 4. DOMEntityReference ノードが見つかった場合、baseURI を取得して出力 51 if ($entityRefNode instanceof DOMEntityReference) { 52 echo "DOMEntityReference ノードが見つかりました (ノード名: " . $entityRefNode->nodeName . ").\n"; 53 54 // baseURI プロパティの値を取得 55 // この baseURI は、DOMEntityReference ノードが属するドキュメント(XMLファイル)の絶対パスです。 56 $baseUri = $entityRefNode->baseURI; 57 58 echo "取得された baseURI: " . ($baseUri ?? 'null') . "\n"; 59 } else { 60 echo "DOMEntityReference ノードは見つかりませんでした。\n"; 61 } 62 63 // 5. 作成した一時ファイルを削除 64 unlink($xmlFilePath); 65} 66 67// 関数を実行 68getDomEntityReferenceBaseUri();
PHPのDOMEntityReferenceクラスが持つbaseURIプロパティは、エンティティ参照ノードが属するドキュメントの絶対ベースURI(Uniform Resource Identifier)を取得するために使用されます。このプロパティは引数を取らず、ノードの基準となるURIを示す文字列を返します。もしURIが不明な場合はnullを返します。
このサンプルコードでは、まず一時的なXMLファイルを作成し、その中に「&appName;」というエンティティ参照を定義しています。DOMDocumentクラスを使ってこのXMLファイルを読み込む際、読み込んだファイルの絶対パスがドキュメント全体のベースURIとして設定されます。次に、DOMXPathを利用してXMLツリーを走査し、エンティティ参照ノード(DOMEntityReferenceオブジェクト)を探します。エンティティ参照ノードが見つかったら、そのbaseURIプロパティにアクセスすることで、PHPでそのノードが属するXMLドキュメントのベースURI(この場合はXMLファイルの絶対パス)を取得できます。取得されたURIは、そのノードが存在する場所や、そこから相対パスを解決する際の基準となる情報を提供します。baseURIプロパティは、XMLドキュメント内で特定のノードがどこに由来するかを正確に知りたい場合に役立ちます。
DOMEntityReference::baseURIは、XMLドキュメント内のエンティティ参照ノードが属するドキュメントの基準URIを取得するプロパティです。これはウェブサイト全体のベースURLとは異なり、XMLファイルが読み込まれた場所のパスや、XMLが外部リソースを参照する際の起点URIを指します。戻り値はstringまたはnullですので、場合によってはURIが取得できないこともある点に留意してください。サンプルコードのように一時ファイルを扱う際には、ファイル作成の権限確認と、処理後のunlinkによる確実なファイル削除が重要です。また、DOM操作はXMLの構造に依存するため、XMLのパースエラーやノードが見つからない場合の適切なエラーハンドリングも考慮すると、より安全に利用できます。