【PHP8.x】DOMNotation::prefixプロパティの使い方
prefixプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
prefixプロパティは、XML文書の要素や属性が持つ名前空間プレフィックスを保持するプロパティです。XMLにおいて、名前空間は同じ名前の要素や属性が異なる意味を持つ場合に、それらの衝突を防ぐために使用されます。この名前空間を識別するために、名前の前にコロン(:)で区切られた短い文字列、すなわちプレフィックスが付けられます。たとえば、「soap:Envelope」という要素がある場合、「soap」がそのプレフィックスにあたります。
このprefixプロパティはDOMNotationクラスに属していますが、DOMNotationはXML文書の<!NOTATION ...>宣言を表す特殊なノードタイプです。NOTATION宣言は、XML文書が参照する外部の非XMLデータ形式(例:画像ファイル)やアプリケーションに関する情報を提供するために用いられます。しかし、この種のノードはXMLの名前空間とは直接関連せず、名前空間プレフィックスを持つことはありません。
そのため、DOMNotationオブジェクトのprefixプロパティにアクセスしても、値は常に空文字列が返されます。このプロパティは、主にDOMElementやDOMAttrのように、実際に名前空間が適用され、プレフィックスを持つことが可能なノードタイプで活用されます。DOMNotationオブジェクトでこのプロパティの値を利用する場面は通常ありませんので、その特性を理解しておくことが重要です。
構文(syntax)
1<?php 2// DOMNotation オブジェクトを間接的に取得する例です。 3// まず、<!NOTATION ...> 宣言を含むXMLドキュメントを読み込みます。 4$dom = new DOMDocument(); 5$dom->loadXML('<!DOCTYPE root [<!NOTATION mynotation SYSTEM "http://example.com/notation-uri">]><root/>'); 6 7$notation = null; 8// ドキュメントタイプと、それに含まれるNOTATION宣言があるかを確認します。 9if ($dom->doctype && $dom->doctype->notations && $dom->doctype->notations->length > 0) { 10 // DOCTYPE から最初の DOMNotation オブジェクトを取得します。 11 $notation = $dom->doctype->notations->item(0); 12} 13 14// DOMNotation オブジェクトが正しく取得できた場合 15if ($notation instanceof DOMNotation) { 16 // DOMNotation オブジェクトの prefix プロパティにアクセスし、その値を取得します。 17 // DOMNotation は通常、XML名前空間プレフィックスを持たないため、このプロパティは null または空文字列を返します。 18 $nodePrefix = $notation->prefix; 19 20 // 取得したプレフィックスを出力します。 21 echo "Notation Prefix: " . ($nodePrefix ?? 'NULL'); 22} else { 23 echo "DOMNotation オブジェクトが見つかりませんでした。"; 24}
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
DOMNotation オブジェクトのプレフィックスを表す文字列を返します。
サンプルコード
PHPで数値をゼロパディングする
1<?php 2 3declare(strict_types=1); 4 5/** 6 * 指定された桁数になるように、数値の先頭を0で埋めます(ゼロパディング)。 7 * 8 * この関数は、ファイル名やIDなどを固定長にしたい場合によく利用されます。 9 * 例: 1 -> 001, 12 -> 012 10 * 11 * @param int $number パディング対象の正の整数。 12 * @param int $digits 最終的な文字列の最小桁数。 13 * @return string 先頭を0で埋められた数値文字列。 14 */ 15function prefixNumberWithZero(int $number, int $digits): string 16{ 17 // sprintf関数を使用して、数値を指定した書式で文字列に変換します。 18 // フォーマット指定子 "%0[桁数]d" は、次のような意味を持ちます。 19 // %: フォーマット指定の開始 20 // 0: 桁数が足りない場合に、空白の代わりに '0' で埋める 21 // [桁数]: 全体の最小桁数を指定 22 // d: 引数を10進数の整数として扱う 23 return sprintf("%0{$digits}d", $number); 24} 25 26// --- 以下、関数の使用例 --- 27 28// ケース1: 1桁の数値を4桁にする 29$number1 = 7; 30$paddedNumber1 = prefixNumberWithZero($number1, 4); 31echo "{$number1} を4桁にすると: {$paddedNumber1}" . PHP_EOL; // 出力: 7 を4桁にすると: 0007 32 33// ケース2: 2桁の数値を4桁にする 34$number2 = 58; 35$paddedNumber2 = prefixNumberWithZero($number2, 4); 36echo "{$number2} を4桁にすると: {$paddedNumber2}" . PHP_EOL; // 出力: 58 を4桁にすると: 0058 37 38// ケース3: 指定した桁数と同じ桁数の数値 39$number3 = 1234; 40$paddedNumber3 = prefixNumberWithZero($number3, 4); 41echo "{$number3} を4桁にすると: {$paddedNumber3}" . PHP_EOL; // 出力: 1234 を4桁にすると: 1234 42 43// ケース4: 指定した桁数より大きい桁数の数値 (この場合、数値は変更されません) 44$number4 = 12345; 45$paddedNumber4 = prefixNumberWithZero($number4, 4); 46echo "{$number4} を4桁にすると: {$paddedNumber4}" . PHP_EOL; // 出力: 12345 を4桁にすると: 12345 47 48?>
このPHPサンプルコードは、数値の先頭に指定した数の「0」を追加し、全体の桁数を揃える方法(ゼロパディング)を示しています。この処理は、連番のファイル名や管理IDなどを固定長に整えたい場合に役立ちます。
コード内で定義されているprefixNumberWithZero関数が、このゼロパディング処理の中心です。この関数は2つの引数を受け取ります。第1引数の$numberには対象となる数値を、第2引数の$digitsには最終的に揃えたい最小の桁数を指定します。
関数内部では、PHPの組み込み関数であるsprintfが使用されています。sprintfは、指定された書式に従って文字列を生成する機能を持っています。ここでは"%0{$digits}d"という書式が指定されており、「渡された数値を10進数の整数として扱い、もし指定桁数に満たない場合は、先頭を0で埋める」という指示を意味します。
この関数の戻り値は、ゼロパディング処理が施された文字列です。例えば、数値7と桁数4を渡すと"0007"という文字列が返されます。なお、元の数値の桁数が指定した桁数以上の場合、数値は変更されずそのまま文字列として返されます。
このコードの核心は、指定した書式で文字列を生成するsprintf関数です。重要な点は、この関数の戻り値が数値ではなく文字列であることです。したがって、返された値でさらに計算を行う場合は、整数などへ型を変換する必要があります。また、指定した桁数よりも元の数値の桁数が大きい場合、数値は切り捨てられずそのまま出力される点にも注意が必要です。この関数は主に正の数を対象としており、負の数を渡すとマイナス記号も文字数に含まれて桁がずれるため、予期せぬ結果になることがあります。安全に利用するために、引数には想定された正の整数を渡すようにしてください。
PHP DOMNotation::prefix で記法プレフィックスを取得する
1<?php 2 3/** 4 * XMLドキュメントから記法(Notation)の名前空間プレフィックスを取得して表示します。 5 * 6 * DOMNotation::prefix プロパティは、記法の名前空間プレフィックスを文字列で返します。 7 * プレフィックスが存在しない場合は、このプロパティは null を返します。 8 */ 9function displayNotationPrefixes(): void 10{ 11 // DTD (文書型定義) 内で記法 (NOTATION) を宣言したXML文字列を定義します。 12 // - 'jpg': プレフィックスなし 13 // - 'img:png': 'img' というプレフィックスあり 14 $xmlString = <<<XML 15 <?xml version="1.0" encoding="UTF-8"?> 16 <!DOCTYPE document [ 17 <!NOTATION jpg PUBLIC "image/jpeg"> 18 <!NOTATION img:png PUBLIC "image/png"> 19 ]> 20 <document /> 21 XML; 22 23 // DOMDocumentオブジェクトを生成します。 24 $doc = new DOMDocument(); 25 26 // DTDを読み込むオプションを有効にしてXMLをロードします。 27 $doc->loadXML($xmlString, LIBXML_DTDLOAD | LIBXML_NOENT); 28 29 // ドキュメントにDOCTYPEが存在し、かつ記法が含まれているかを確認します。 30 if ($doc->doctype && $doc->doctype->notations->length > 0) { 31 echo "DTDから検出された記法(Notation)のプレフィックス:" . PHP_EOL; 32 echo "-----------------------------------------" . PHP_EOL; 33 34 // 記法のリスト (DOMNamedNodeMap) をループ処理します。 35 /** @var DOMNotation $notation */ 36 foreach ($doc->doctype->notations as $notation) { 37 // prefix プロパティで名前空間プレフィックスを取得します。 38 $prefix = $notation->prefix; 39 40 printf( 41 "記法名: %-10s -> プレフィックス: %s" . PHP_EOL, 42 $notation->nodeName, // 例: 'img:png' 43 $prefix ?? 'なし' // 例: 'img' (null の場合は 'なし' を表示) 44 ); 45 } 46 } else { 47 echo "有効な記法(Notation)が見つかりませんでした。"; 48 } 49} 50 51// 関数を実行して結果を表示します。 52displayNotationPrefixes(); 53 54?>
このPHPサンプルコードは、XML文書のDTD(文書型定義)で宣言された記法(Notation)の名前空間プレフィックスを取得し、表示する方法を解説しています。中心となるのはDOMNotationクラスのprefixプロパティです。
DOMNotation::prefixは、特定の記法に付けられた名前空間プレフィックスを文字列として取得するためのプロパティです。このプロパティは引数を必要としません。
コード内では、まず<!NOTATION>を用いて'jpg'(プレフィックスなし)と'img:png'(プレフィックスあり)の2つの記法を定義したXMLを読み込みます。次に、$doc->doctype->notationsを通じて記法のリストを取得し、foreachループで一つずつ処理します。ループ内で$notation->prefixにアクセスすることで、各記法のプレフィックスを取得しています。
このプロパティの戻り値は文字列(string)です。記法名に'img:png'のようにコロン(:)で区切られたプレフィックスが存在する場合、その部分(この例では'img')を返します。プレフィックスが存在しない'jpg'のような記法の場合はnullを返します。これにより、XMLで定義された記法がどの名前空間に属しているかを簡単に判別できます。
DOMNotation::prefixプロパティは、XMLのDTD(文書型定義)で宣言された記法の名前に含まれる名前空間プレフィックスを取得します。この機能を利用するには、DOMDocument::loadXMLメソッドの実行時にLIBXML_DTDLOADオプションを指定して、DTDを明示的に読み込む必要があります。これを忘れると記法が認識されません。また、prefixプロパティは、記法名にプレフィックス(コロン:より前の部分)が存在しない場合、文字列ではなくnullを返します。そのため、取得した値を利用する際は、サンプルコードのようにnull合体演算子(??)などを用いてnullの場合の処理を記述することが重要です。このプロパティは読み取り専用であり、値を代入してプレフィックスを変更することはできません。