第1回では、PHPで名前空間が必要な理由と、予約名の名前空間の意味について説明しました。 この記事では、useステートメントと、PHPが名前空間名を解決する方法について説明します。
この記事の目的上、2つのほぼ同一のコードを使用しますが、唯一の違いは名前空間にあります。
lib1.php:
<?php // application library 1 namespace App\Lib1; const MYCONST = 'App\Lib1\MYCONST'; function MyFunction() { return __FUNCTION__; } class MyClass { static function WhoAmI() { return __METHOD__; } } ?>
lib2.php:
<?php // application library 2 namespace App\Lib2; const MYCONST = 'App\Lib2\MYCONST'; function MyFunction() { return __FUNCTION__; } class MyClass { static function WhoAmI() { return __METHOD__; } } ?>
始める前に、PHPの用語からいくつかの定義を思い出してみましょう。
完全修飾名
PHPコードは、完全修飾名(名前空間区切り文字(バックスラッシュ)で始まる識別子)を参照できます。例:\ App \ Lib1 \ MYCONST、\ App \ Lib2 \ MyFunction()など。
完全修飾名にあいまいさはありません。 最初のバックスラッシュはファイルパスと同じように機能し、グローバルスペースの「ルート」を示します。 グローバルスペースでさまざまなMyFunction()を実行する場合、\ MyFunction()を使用してlib1.phpまたはlib2.phpから呼び出すことができます。
完全修飾名は、1回限りの関数呼び出しやオブジェクトの初期化に役立ちます。 ただし、多くの課題を作成すると、それらは非現実的になります。 以下で学習するように、PHPはこれらの場合に他のオプションを提供します。
修飾名
Lib1 \ MyFunction()など、少なくとも1つの名前空間セパレーター(実際にはバックスラッシュ)を持つ識別子。
非修飾名
MyFunction()など、名前空間区切り文字のない識別子。
同じ名前空間で作業する
次のコードについて説明します。
myapp1.php:
<?php namespace App\Lib1; require_once('lib1.php'); require_once('lib2.php'); header('Content-type: text/plain'); echo MYCONST . "\n"; echo MyFunction() . "\n"; echo MyClass::WhoAmI() . "\n"; ?>
lib1.phpとlib2.phpの両方を添付しましたが、識別子MYCONST、MyFunction、およびMyClassはlib1.phpのみを参照します。 これは、コードmyapp1.phpがApp \ Lib1と同じネームスペースにあるために発生します。
結果:
App\Lib1\MYCONST App\Lib1\MyFunction App\Lib1\MyClass::WhoAmI
名前空間のインポート(名前空間のインポート)
名前空間は、useステートメントを使用してインポートできます。次に例を示します。
myapp2.php:
<?php use App\Lib2; require_once('lib1.php'); require_once('lib2.php'); header('Content-type: text/plain'); echo Lib2\MYCONST . "\n"; echo Lib2\MyFunction() . "\n"; echo Lib2\MyClass::WhoAmI() . "\n"; ?>
1つ以上の名前空間を使用してインポートし、それらをコンマで区切ることができます。 この例では、App \ Lib2名前空間をインポートしました。 MYCONST、MyFunction、またはMyClassを直接参照することはできません。コードがグローバルスペースにあり、PHPがそれらを検索するためです。 しかし、接頭辞「Lib2 \」を追加すると、それらは修飾名になり、PHPは完全に一致するまでインポートされた名前空間でそれらを探します。
結果:
App\Lib2\MYCONST App\Lib2\MyFunction App\Lib2\MyClass::WhoAmI
名前空間のエイリアス
ネームスペースエイリアスは、おそらく最も便利な構成要素です。 エイリアスを使用すると、短い名前を使用して長い名前空間を参照できます。
myapp3.php:
<?php use App\Lib1 as L; use App\Lib2\MyClass as Obj; header('Content-type: text/plain'); require_once('lib1.php'); require_once('lib2.php'); echo L\MYCONST . "\n"; echo L\MyFunction() . "\n"; echo L\MyClass::WhoAmI() . "\n"; echo Obj::WhoAmI() . "\n"; ?>
最初のuseステートメントは、App \ Lib1を「L」として定義します。 「L」を使用する修飾名は、コンパイル時に「App \ Lib1」に変換されます。 したがって、完全修飾名ではなく、L \ MYCONSTまたはL \ MyFunctionを参照します。
2番目のuseステートメントはより興味深いものです。 ObjをApp \ Lib2 \名前空間内のMyClassクラスのエイリアスとして定義します。 この操作はクラスにのみ適用され、定数や関数には適用されません。 上記のように、新しいObj()を使用するか、静的メソッドを呼び出すことができます。
結果:
App\Lib1\MYCONST App\Lib1\MyFunction App\Lib1\MyClass::WhoAmI App\Lib2\MyClass::WhoAmI
解析ルール
PHP識別子名は、次の名前空間規則によって解決されます。 詳細については、PHPマニュアルを参照してください( 英語 / ロシア語 )
- コンパイル中に修飾関数を呼び出すことは許可されています。
- すべての修飾名は、現在インポートされている名前空間に従ってコンパイル時に変換されます。 たとえば、名前空間A :: B :: Cがインポートされた場合、C :: D :: e()への呼び出しは、A :: B :: C :: D :: e()として変換されます。
- 名前空間内では、すべての修飾名がインポート規則に従って変換されます。たとえば、名前空間A \ B \ CがCとしてインポートされる場合、呼び出しC \ D \ e()はA \ B \ C \ D \ e()に変換されます。
- 修飾されていないクラス名は、現在のインポートされた名前空間に従ってコンパイル時に変換され、完全な名前は短いインポート名に置き換わります。たとえば、A \ B名前空間のクラスCがXとしてインポートされる場合、新しいX()は新しいA \ B \ Cに変換されます()。
- 名前空間内では、未熟な関数の呼び出しはコンパイル時に解釈されます。 たとえば、My Function()がA \ B名前空間内で呼び出された場合、PHPは最初に関数\ A \ B \ MyFunction()を検索します。 見つからない場合、PHPはグローバルスペースで\ MyFunction()を探します。
- スキルのないクラスまたは修飾されたクラス名の呼び出しは、コンパイル時に解釈されます。 たとえば、名前空間A \ B内でnew C()を呼び出すと、PHPはクラスA \ B \ Cを探します。 見つからない場合は、A \ B \ Cを自動ロードしようとします。
次の部分では、キーワードとスタートアップ。
また読む:
PHPで名前空間を使用する方法、パート1:基本
PHPで名前空間を使用する方法、パート3:キーワードと起動
注:
A /備考、修正、不正確さの表示など - ようこそ !
B / ソースコードハイライターで強調表示されたコード 。