【PHP8.x】DOMEntity::prefixプロパティの使い方
prefixプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
prefixプロパティは、所属するDOMEntityオブジェクトが表すXMLエンティティ宣言の名前空間プレフィックスを保持するプロパティです。
XMLの名前空間とは、XMLドキュメント内で要素名や属性名が重複するのを避けるために使用される仕組みです。例えば、<ns:element>という記述があった場合、nsの部分が名前空間プレフィックスにあたり、elementという要素がどの名前空間に属するかを示します。
DOMEntityクラスは、XMLドキュメント型定義(DTD)やスキーマで定義されるエンティティ宣言、例えば <!ENTITY copyright "© My Company"> のようなものを表すオブジェクトです。このエンティティ宣言の「名前」(上記の例では copyright)自体に名前空間プレフィックスが付与されることは、XMLの標準的な利用方法においては非常に稀です。
そのため、通常、DOMEntityオブジェクトのprefixプロパティはnullまたは空の文字列を返します。これは、そのエンティティ名が特定され、名前空間の識別子が不要であることを意味します。
このプロパティは、DOMEntityが継承しているDOMNodeクラスが持つ一般的なプロパティの一つです。他の種類のノード、例えば名前空間プレフィックスを持つXML要素や属性ノードの場合には、このprefixプロパティにそのプレフィックスが格納されますが、DOMEntityの場合はその性質上、基本的に値を持たないという点を理解しておくことが重要です。
このプロパティを通じて、ノードが持つ名前空間プレフィックスの有無やその値を確認できますが、DOMEntityの場合、その利用ケースは限定的であると言えます。
構文(syntax)
1<?php 2 3$dom = new DOMDocument(); 4$dom->loadXML('<!DOCTYPE doc [<!ENTITY myentity SYSTEM "http://example.com/some.dtd">]> <root/>'); 5 6// DOMDocumentTypeからエンティティのコレクションを取得 7$entities = $dom->doctype->entities; 8 9// 最初のDOMEntityオブジェクトを取得 10$entity = $entities->item(0); 11 12// DOMEntityオブジェクトのprefixプロパティにアクセスする構文 13$prefixValue = $entity->prefix;
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
DOMEntityオブジェクトの接頭辞を表す文字列を返します。
サンプルコード
PHPで数値を0埋めパディングする
1<?php 2 3declare(strict_types=1); 4 5/** 6 * 指定された桁数になるように、数値の前に'0'を付加(ゼロパディング)します。 7 * 8 * PHPの組み込み関数 `sprintf` を使用するのが一般的です。 9 * フォーマット文字列 '%0Xd' は、X桁の10進数(d)を、 10 * 足りない部分をゼロ(0)で埋めることを意味します。 11 * 12 * @param int $number 対象の整数。 13 * @param int $length 結果として得たい文字列の最小長(桁数)。 14 * @return string ゼロでパディングされた数値を表す文字列。 15 */ 16function prefixNumberWithZero(int $number, int $length): string 17{ 18 // sprintf を使用して、指定された桁数になるように数値を'0'でパディングする 19 return sprintf("%0{$length}d", $number); 20} 21 22// --- 使用例 --- 23 24// 数値 5 を 2 桁の文字列 '05' に変換する 25$number1 = 5; 26$length1 = 2; 27$result1 = prefixNumberWithZero($number1, $length1); 28echo "数値 {$number1} を {$length1} 桁にパディングした結果: {$result1}" . PHP_EOL; 29 30// 数値 123 を 5 桁の文字列 '00123' に変換する 31$number2 = 123; 32$length2 = 5; 33$result2 = prefixNumberWithZero($number2, $length2); 34echo "数値 {$number2} を {$length2} 桁にパディングした結果: {$result2}" . PHP_EOL; 35 36// 元の数値が指定した桁数以上の場合、パディングは行われない 37$number3 = 9876; 38$length3 = 4; 39$result3 = prefixNumberWithZero($number3, $length3); 40echo "数値 {$number3} を {$length3} 桁にパディングした結果: {$result3}" . PHP_EOL; 41 42?>
このPHPサンプルコードは、指定した桁数になるように、数値の前に'0'を付けて文字列に変換する「ゼロパディング」という処理を実装しています。
コード内で定義されている prefixNumberWithZero 関数は、2つの引数を受け取ります。第1引数の $number には処理対象となる整数を、第2引数の $length には最終的に揃えたい文字列の桁数を指定します。関数の戻り値は、ゼロでパディングされた数値を表す文字列です。
この機能は、PHPに標準で組み込まれている sprintf 関数を利用して実現されています。sprintf は、指定された書式(フォーマット)に従って文字列を生成する便利な関数です。コード中の "%0{$length}d" という書式は、「整数(d)を $length で指定された桁数で表現し、足りない桁は先頭をゼロ(0)で埋める」という指示を意味します。
例えば、数値 5 と桁数 2 をこの関数に渡すと、文字列 '05' が返されます。もし元の数値の桁数が指定した桁数以上の場合、例えば数値 9876 と桁数 4 を渡した場合は、ゼロは付加されず、そのまま文字列 '9876' が返されます。この処理は、連番のファイル名や日付の表示など、桁数を固定したい場面で広く利用されます。
このコードは、数値を指定した桁数の文字列に変換する際、足りない部分をゼロで埋める処理です。注意点として、この関数の戻り値は数値(integer)ではなく文字列(string)であるため、その後の計算で使う場合は数値への型変換が必要です。また、sprintf関数では、元の数値の桁数が指定した桁数以上の場合、文字列が切り捨てられることはなく、元の数値がそのまま文字列になります。コード冒頭のdeclare(strict_types=1);により、この関数には必ず整数を渡す必要があり、文字列の数字などを渡すとエラーになる点にも注意してください。負の数を扱う場合、マイナス記号も桁数に含まれてパディングされるため、予期せぬ結果になる可能性があります。
PHP DOMEntity prefixプロパティを表示する
1<?php 2 3/** 4 * DOMEntityのprefixプロパティの使用例を示します。 5 * 6 * このコードは、XML文書のDTD(文書型定義)で定義されたエンティティを取得し、 7 * そのprefixプロパティの値を表示します。 8 */ 9function getDomEntityPrefixExample(): void 10{ 11 // DTD内で 'copyright' という名前のエンティティを定義したXML文字列 12 $xmlString = <<<XML 13 <?xml version="1.0" encoding="UTF-8"?> 14 <!DOCTYPE note [ 15 <!ENTITY copyright "Copyright 2023. All rights reserved."> 16 ]> 17 <note> 18 <content>This is a sample document.</content> 19 <footer>©right;</footer> 20 </note> 21 XML; 22 23 // DOMDocumentオブジェクトを作成し、XMLを読み込みます 24 $dom = new DOMDocument(); 25 $dom->loadXML($xmlString); 26 27 // DTDから 'copyright' という名前のエンティティ(DOMEntityオブジェクト)を取得します 28 // $dom->doctype->entities はエンティティのリスト(DOMNamedNodeMap)です 29 $entity = $dom->doctype->entities->getNamedItem('copyright'); 30 31 // DOMEntityのprefixプロパティを取得します 32 // エンティティノードは名前空間を持たないため、prefixプロパティは 33 // 常に空の文字列("")を返します (PHP 8.0以降)。 34 $prefix = $entity->prefix; 35 36 // 結果を出力します 37 echo "エンティティ名 (nodeName): " . $entity->nodeName . PHP_EOL; 38 echo "プレフィックス (prefix): "; 39 var_dump($prefix); 40} 41 42// 関数を実行します 43getDomEntityPrefixExample(); 44 45?>
DOMEntityクラスのprefixプロパティは、XML文書のDTD(文書型定義)で定義されたエンティティの名前空間プレフィックスを取得します。このプロパティは引数を取らず、戻り値として名前空間プレフィックスを表す文字列(string)を返します。
サンプルコードでは、まずDTDでcopyrightという名前のエンティティを定義したXML文字列を読み込みます。次に、doctypeプロパティとentitiesプロパティを経由してcopyrightエンティティを表すDOMEntityオブジェクトを取得し、そのprefixプロパティの値を変数に代入しています。
PHP 8.0以降の仕様では、エンティティノードは名前空間を持つことができません。そのため、DOMEntityのprefixプロパティは常に空の文字列("")を返します。サンプルコードを実行すると、var_dumpによって空の文字列が出力されますが、これはこの仕様による正しい挙動です。このプロパティは、他のDOMノードオブジェクトとの一貫性を保つために存在しています。
DOMEntityのprefixプロパティは、エンティティ自体がXMLの名前空間を持たないという仕様のため、PHP 8.0以降では常に空の文字列を返します。このプロパティから名前空間の接頭辞を取得しようとしても、値は得られない点に注意してください。サンプルコードを参考にエンティティを扱う際は、対象のXML文書にDTD(文書型定義)が含まれていることが前提です。もしDTDが存在しない場合、$dom->doctypeがnullとなりエラーが発生します。また、getNamedItem()で指定したエンティティが見つからない場合もnullが返されるため、取得したオブジェクトのプロパティにアクセスする前に、nullでないことを確認するとより安全なコードになります。