【PHP8.x】DOMEntity::encodingプロパティの使い方
encodingプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
encodingプロパティは、DOMツリー内のエンティティのエンコーディング情報を保持するプロパティです。
PHPのDOM拡張機能では、XMLドキュメントで定義されるエンティティをDOMEntityクラスで扱います。エンティティとは、XMLドキュメント内で名前を付けて定義し、再利用できる特定のテキストやマークアップの塊のことです。
このencodingプロパティは、そのDOMEntityオブジェクトが表すエンティティがどの文字エンコーディング(例えば、UTF-8やShift-JISなど)で定義されているかを示す文字列です。
XMLパーサは、エンティティの内容を正しく解釈するためにこのエンコーディング情報を使用します。特に、エンティティのエンコーディングがドキュメント全体のエンコーディングと異なる場合や、多言語データを含む場合に重要です。
このプロパティは読み取り専用であり、DOMEntityオブジェクトがXMLドキュメントから生成される際に、エンティティ定義に基づき自動的に値が設定されます。
システムエンジニアを目指す初心者の方にとって、XMLドキュメント処理で文字化けが発生した場合や、エンティティの内容を正確に取得する必要がある際に、このencodingプロパティの値がデバッグや問題解決に役立つことがあります。XMLデータを扱う上での正確な文字処理の基礎として理解しておきましょう。
構文(syntax)
1<?php 2$dom = new DOMDocument(); 3$dom->loadXML('<!DOCTYPE root [<!ENTITY myentity SYSTEM "data:text/plain;charset=UTF-8,hello">]><root>&myentity;</root>'); 4$entity = $dom->doctype->entities->item(0); 5$encoding = $entity->encoding;
引数(parameters)
引数なし
引数はありません
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP DOMEntityのencodingプロパティとmbstringエンコーディングリストを照合する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * XMLドキュメント内のエンティティのエンコーディング情報を取得して表示します。 7 * 8 * このサンプルでは、DOMEntity クラスの `encoding` プロパティを使用して、 9 * DTD(文書型定義)で指定された外部エンティティの文字エンコーディングを取得します。 10 * さらに、キーワード 'php encoding list' に関連し、PHPがサポートする 11 * エンコーディングのリスト (mb_list_encodings) と照合します。 12 */ 13function showEntityEncodingExample(): void 14{ 15 // 内部DTDサブセットを持つXML文字列を準備します。 16 // 'myEntity' というエンティティを定義し、そのエンコーディングを 'UTF-16' と指定します。 17 $xmlString = <<<XML 18 <?xml version="1.0" encoding="UTF-8"?> 19 <!DOCTYPE document [ 20 <!ENTITY myEntity SYSTEM "data.txt" NDATA text ENCODING "UTF-16"> 21 ]> 22 <document> 23 <content>Some content here.</content> 24 </document> 25 XML; 26 27 // DOMDocumentオブジェクトを生成します。 28 $dom = new DOMDocument(); 29 30 // XML文字列を読み込みます。DTDも読み込むためにLIBXML_DTDLOADフラグが必要です。 31 $dom->loadXML($xmlString, LIBXML_DTDLOAD); 32 33 // ドキュメントのDOCTYPE定義を取得します。 34 $doctype = $dom->doctype; 35 36 // DOCTYPEが存在し、エンティティのリストが含まれていることを確認します。 37 if ($doctype instanceof DOMDocumentType && $doctype->entities instanceof DOMNamedNodeMap) { 38 // 'myEntity' という名前のエンティティオブジェクト(DOMEntity)を取得します。 39 /** @var DOMEntity|null $entity */ 40 $entity = $doctype->entities->getNamedItem('myEntity'); 41 42 if ($entity instanceof DOMEntity) { 43 // DOMEntity::$encoding プロパティからエンコーディング名を取得します。 44 // このプロパティは読み取り専用です。 45 $entityEncoding = $entity->encoding; 46 47 echo "エンティティ名: " . $entity->nodeName . PHP_EOL; 48 echo "指定されたエンコーディング: " . $entityEncoding . PHP_EOL; 49 50 // PHPがサポートするエンコーディングのリストを取得します。 51 $supportedEncodings = mb_list_encodings(); 52 53 // 取得したエンコーディングがサポートリストに含まれるか確認します。 54 if (in_array($entityEncoding, $supportedEncodings, true)) { 55 echo "-> このエンコーディングはPHPのmbstring拡張機能でサポートされています。" . PHP_EOL; 56 } else { 57 echo "-> このエンコーディングはPHPのmbstring拡張機能ではサポートされていません。" . PHP_EOL; 58 } 59 } else { 60 echo "エンティティ 'myEntity' が見つかりませんでした。" . PHP_EOL; 61 } 62 } else { 63 echo "DTDまたはエンティティ定義が見つかりませんでした。" . PHP_EOL; 64 } 65} 66 67// 関数を実行してサンプルコードの結果を表示します。 68showEntityEncodingExample();
DOMEntityクラスのencodingプロパティは、XML文書のDTD(文書型定義)で定義された、解析対象外の外部エンティティに指定された文字エンコーディング名を取得します。このプロパティは値を参照するだけであり、引数や戻り値はありません。また、値の変更はできない読み取り専用です。
このサンプルコードでは、まずDTDを含むXML文字列を準備します。DTD内ではmyEntityというエンティティを定義し、そのエンコーディングをENCODING属性で "UTF-16" と指定しています。次に、DOMDocumentクラスでXMLを解析し、文書のDOCTYPE定義からmyEntityという名前のDOMEntityオブジェクトを取得します。
そして、$entity->encodingのようにプロパティにアクセスすることで、DTDで指定されたエンコーディング名(この例では "UTF-16")を文字列として取得し、表示します。さらに、取得したエンコーディング名がPHPのmb_list_encodings関数で得られるサポート対象の一覧に含まれるかを確認し、PHPのmbstring拡張機能で扱えるエンコーディングであるかを判定しています。
DOMEntityのencodingプロパティは、XMLのDTDで定義された外部エンティティのエンコーディング情報を取得します。この機能を利用するには、DOMDocument::loadXML関数でXMLを読み込む際に、第二引数へLIBXML_DTDLOADフラグを必ず指定する必要があります。この指定がないとDTDが解釈されず、エンティティ情報を取得できません。また、このプロパティは読み取り専用のため、値を代入しようとするとエラーになります。DTDでエンコーディングが指定されていない場合、プロパティはnullを返すため、利用前にはnullでないことを確認するのが安全です。取得したエンコーディング名がPHPで実際に扱えるかは別問題なので注意が必要です。
PHPでXMLのエンコーディングを取得する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * XMLドキュメントのエンコーディングを取得して表示します。 7 * 8 * DOMDocumentのencodingプロパティは、XML宣言で指定されたエンコーディングを返します。 9 * このプロパティは読み取り専用です。 10 * ※リファレンス情報の「DOMEntity」は「DOMDocument」の誤りである可能性が高いため、 11 * DOMDocumentのプロパティとして実装します。 12 */ 13function displayXmlEncoding(): void 14{ 15 // エンコーディングがUTF-8で指定されたXML文字列を準備 16 $xmlString = <<<XML 17<?xml version="1.0" encoding="UTF-8"?> 18<root> 19 <message>こんにちは、世界!</message> 20</root> 21XML; 22 23 // DOMDocumentオブジェクトを生成 24 $dom = new DOMDocument(); 25 26 // XML文字列を読み込む 27 $dom->loadXML($xmlString); 28 29 // encodingプロパティを使ってドキュメントのエンコーディングを取得 30 // このプロパティはXML宣言のencoding属性の値に対応します 31 $encoding = $dom->encoding; 32 33 // 取得したエンコーディングを表示 34 echo 'XML Document Encoding: ' . $encoding . PHP_EOL; 35} 36 37// 関数を実行 38displayXmlEncoding(); 39 40?>
このサンプルコードは、PHPのDOM拡張機能を使って、XML文字列から文字エンコーディング情報を取得し、画面に表示するプログラムです。
最初に、new DOMDocument() を使ってXML文書を操作するためのオブジェクトを生成します。続いて loadXML() メソッドが、$xmlString 変数に格納されたXML形式の文字列を読み込み、オブジェクトが扱えるように内部で解析します。
コードの中心となるのが $dom->encoding です。これは DOMDocument オブジェクトのプロパティで、読み込んだXMLデータのXML宣言(<?xml ... ?>の部分)で指定されている encoding 属性の値を取得する役割を持ちます。このプロパティは値を読み取ることだけが可能で、引数は必要ありません。サンプルではXML宣言が encoding="UTF-8" となっているため、文字列 "UTF-8" が取得され、変数 $encoding に代入されます。
最後に、取得したエンコーディングの文字列を echo を使って画面に出力します。このように encoding プロパティを利用することで、プログラムでXMLデータを扱う際に、そのデータがどの文字コードで記述されているかを簡単に確認することができます。
DOMDocumentのencodingプロパティは、XML宣言に記載されたエンコーディング情報を取得するための読み取り専用のプロパティです。このプロパティに値を代入して、ドキュメントのエンコーディングを変更することはできない点に注意してください。また、XMLデータ内に<?xml version="1.0" encoding="..."?>のようなエンコーディング指定を持つXML宣言が存在しない場合、このプロパティはnullを返します。このプロパティが返す値は、あくまで宣言に書かれている文字列であり、PHPが内部で文字列を扱う際の実際の文字コードを保証するものではありません。