Forum und email

名前解決の規則

名前解決は、以下の規則に基づいて行います。

  1. すべての修飾名が、コンパイル時に import の指定にあわせて変換されます。 たとえば、名前空間 A::B::C をインポートした環境で C::D::e() をコールすると、それが A::B::C::D::e() に変換されます。
  2. 修飾されていないクラス名が、コンパイル時に import の指定にあわせて変換されます (短い名前を完全な名前に変換します)。 たとえば、名前空間 A::B::C をインポートした環境では new C()new A::B::C() に変換されます。
  3. 名前空間の中で、修飾されていない関数コールのうち、現在の名前空間で定義されているもの (そしてその関数コールをパースする時点で既知のもの) については、 現在の名前空間の関数に変換されます。
  4. 名前空間 (たとえば A::B) の中で、修飾されていない関数コールのうち、 現在の名前空間では定義されていないものについては実行時に解決されます。 関数 foo() のコールは、次のように解決されます。
    1. 現在の名前空間の関数 A::B::foo() を探します。
    2. 内部関数 foo() を探します。
    グローバル名前空間にあるユーザ定義の関数をコールするには、 ::foo() とする必要があります。
  5. 名前空間 (たとえば A::B) の中で、 修飾されていないクラス名については実行時に解決されます。 new C() のコールは、次のように解決されます。
    1. 現在の名前空間のクラス A::B::C() を探します。
    2. 内部クラス C() を探します。
    3. A::B::C()C() の autoload を試みます。
    グローバル名前空間にあるユーザ定義のクラスを参照するには new ::C() とする必要があります。
  6. 修飾されている関数コールを実行時に解決します。 A::B::foo() のコールは、次のように解決されます。
    1. 名前空間 A::B の関数 foo() を探します。
    2. クラス A::B を探し、その静的メソッド foo() をコールします。 必要に応じてクラスを autoload します。
  7. 修飾されているクラス名を、コンパイル時にその名前空間のクラスとして解決します。 たとえば new A::B::C() は、名前空間 >A::B のクラス C を指します。

Example#1 名前解決の解説

<?php
namespace A
;

// 関数コール

<?php
namespace A
;

// 関数コール

foo();      // まずは名前空間 "A" の関数 "foo" のコールを試み、
            // それがなければ内部関数 "foo" をコールします

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

// クラスの参照

new B();    // まずは名前空間 "A" で定義されているクラス "B" のオブジェクトの作成を試み、
            // それがなければ内部クラス "B" のオブジェクトを作成します

new ::B();  // グローバルスコープで定義されているクラス "B" のオブジェクトをします

// 他の名前空間の静的メソッド/関数

B::foo();   // まずは名前空間 "A::B" の関数 "foo" のコールを試み、
            // 次に内部クラス "B" のメソッド "foo" をコールします

::B::foo(); // まずは名前空間 "B" の関数 "foo" のコールを試み、
            // 次にグローバルスコープのクラス "B" のメソッド "foo" をコールします

// 現在の名前空間の静的メソッド/関数

A::foo();   // まずは名前空間 "A::A" の関数 "foo" のコールを試み、
            // 次に名前空間 "A" のクラス "A" のメソッド "foo"、
            // それから名前空間 "A" の関数 "foo"、
            // さらにその次に内部クラス "A" のメソッド "foo" という順になります

::A::foo(); // まずは名前空間 "A" の関数 "foo" のコールを試み、次に
            // グローバルスコープのクラス "A" のメソッド "foo" をコールします
?>