名前解決のルール

(PHP 5 >= 5.3.0, PHP 7)

名前解決のルールを説明するにあたって、いくつかの重要な定義を示しておきます。

名前空間名の定義
非修飾名

これは名前空間区切り文字を含まない識別子で、Foo のようなものです。

修飾名

これは名前空間区切り文字を含む識別子で、Foo\Bar のようなものです。

完全修飾名

これは名前空間区切り文字を含む識別子のうち先頭が名前空間区切り文字で始まるもので、 \Foo\Bar のようなものです。名前空間 \Foo も完全修飾名です。

Relative name

This is an identifier starting with namespace, such as namespace\Foo\Bar.

名前解決は、これらの解決ルールによって行われます。

  1. Fully qualified names always resolve to the name without leading namespace separator. たとえば、\A\BA\B と解釈されます。
  2. Relative names always resolve to the name with namespace replaced by the current namespace. If the name occurs in the global namespace, the namespace\ prefix is stripped. For example namespace\A inside namespace X\Y resolves to X\Y\A. The same name inside the global namespace resolves to A.
  3. For qualified names the first segment of the name is translated according to the current class/namespace import table. For example, if the namespace A\B\C is imported as C, the name C\D\E is translated to A\B\C\D\E.
  4. For qualified names, if no import rule applies, the current namespace is prepended to the name. For example, the name C\D\E inside namespace A\B, resolves to A\B\C\D\E.
  5. For unqualified names, the name is translated according to the current import table for the respective symbol type. This means that class-like names are translated according to the class/namespace import table, function names according to the function import table and constants according to the constant import table. For example, after use A\B\C; a usage such as new C() resolves to the name A\B\C(). Similarly, after use function A\B\fn; a usage such as fn() resolves to the name A\B\fn.
  6. For unqualified names, if no import rule applies and the name refers to a class-like symbol, the current namespace is prepended. For example new C() inside namespace A\B resolves to name A\B\C.
  7. For unqualified names, if no import rule applies and the name refers to a function or constant and the code is outside the global namespace, the name is resolved at runtime. Assuming the code is in namespace A\B, 関数 foo() のコールは、次のように解決されます。
    1. まず現在の名前空間から関数 A\B\foo() を探します。
    2. 次に グローバル 関数 foo() を探します。

例1 名前解決の例

<?php
namespace A;
use 
B\DC\as F;

// 関数のコール

foo();      // まず名前空間 "A" で定義されている "foo" のコールを試み、
            // 次にグローバル関数 "foo" をコールします

\foo();     // グローバルスコープで定義されている関数 "foo" をコールします

my\foo();   // 名前空間 "A\my" で定義されている関数 "foo" をコールします

F();        // まず名前空間 "A" で定義されている "F" のコールを試み、
            // 次にグローバル関数 "F" をコールします

// クラスの参照

new B();    // 名前空間 "A" で定義されているクラス "B" のオブジェクトを作成します
            // 見つからない場合は、クラス "A\B" の autoload を試みます

new D();    // インポートルールを使用し、名前空間 "B" で定義されているクラス "D" のオブジェクトを作成します
            // 見つからない場合は、クラス "B\D" の autoload を試みます

new F();    // インポートルールを使用し、名前空間 "C" で定義されているクラス "E" のオブジェクトを作成します
            // 見つからない場合は、クラス "C\E" の autoload を試みます

new \B();   // グローバルスコープで定義されているクラス "B" のオブジェクトを作成します
            // 見つからない場合は、クラス "B" の autoload を試みます

new \D();   // グローバルスコープで定義されているクラス "D" のオブジェクトを作成します
            // 見つからない場合は、クラス "D" の autoload を試みます

new \F();   // グローバルスコープで定義されているクラス "F" のオブジェクトを作成します
            // 見つからない場合は、クラス "F" の autoload を試みます

// 別の名前空間から使用する静的メソッド/関数

B\foo();    // 名前空間 "A\B" の関数 "foo" をコールします

B::foo();   // 名前空間 "A" で定義されているクラス "B" のメソッド "foo" をコールします
            // クラス "A\B" が見つからない場合はクラス "A\B" の autoload を試みます

D::foo();   // インポートルールを使用し、名前空間 "B" で定義されているクラス "D" のメソッド "foo" をコールします
            // クラス "B\D" が見つからない場合はクラス "B\D" の autoload を試みます

\B\foo();   // 名前空間 "B" の関数 "foo" をコールします

\B::foo();  // グローバルスコープのクラス "B" のメソッド "foo" をコールします
            // クラス "B" が見つからない場合はクラス "B" の autoload を試みます

// 現在の名前空間から使用する静的メソッド/関数

A\B::foo();   // 名前空間 "A\A" のクラス "B" のメソッド "foo" をコールします
              // クラス "A\A\B" が見つからない場合はクラス "A\A\B" の autoload を試みます

\A\B::foo();  // 名前空間 "A" のクラス "B" のメソッド "foo" をコールします
              // クラス "A\B" が見つからない場合はクラス "A\B" の autoload を試みます
?>