이름 확인 규칙
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
이러한 해결 규칙의 목적을 위해 다음은 몇 가지 중요한 정의입니다.
-
네임스페이스 이름 정의
- Unqualified name
Foo
와 같이 네임스페이스 구분 기호가 없는 식별자입니다.- Qualified name
Foo\Bar
와 같이 네임스페이스 구분 기호가 있는 식별자입니다.- Fully qualified name
- 이것은
\Foo\Bar
와 같이 네임스페이스 구분자로 시작하는 네임스페이스 구분자가 있는 식별자입니다. 네임스페이스\Foo
도 정규화된 이름입니다. - Relative name
- 이는
namespace\Foo\Bar
와 같이 네임스페이스로 시작하는 식별자입니다.
이름은 다음 확인 규칙에 따라 확인됩니다.
- 정규화된 이름은 항상 선행 네임스페이스 구분 기호가 없는 이름으로 확인됩니다. 예를 들어
\A\B
는\A\B
로 해석됩니다. - 상대 이름은 항상 현재 네임스페이스로 대체된
namespace
가 있는 이름으로 확인됩니다. 이름이 전역 네임스페이스에 있으면namespace\
접두사가 제거됩니다. 예를 들어 네임스페이스X\Y
내부의namespace\A
는X\Y\A
로 확인됩니다. 전역 네임스페이스 내부의 동일한 이름은A
로 확인됩니다. - 규정된 이름의 경우 이름의 첫 번째 세그먼트는 현재 클래스/네임스페이스 가져오기 테이블에 따라 변환됩니다. 예를 들어, 네임스페이스
A\B\C
를C
로 가져오면 이름C\D\E
는A\B\C\D\E
로 변환됩니다. - 정규화된 이름의 경우 가져오기 규칙이 적용되지 않으면 현재 네임스페이스가 이름 앞에 추가됩니다. 예를 들어 네임스페이스
A\B
내의C\D\E
이름은A\B\C\D\E
로 확인됩니다. - 규정되지 않은 이름의 경우 해당 기호 유형에 대한 현재 가져오기 테이블에 따라 이름이 변환됩니다. 즉, 클래스와 같은 이름은 클래스/네임스페이스 가져오기 테이블에 따라, 함수 이름은 함수 가져오기 테이블에 따라, 상수는 상수 가져오기 테이블에 따라 변환됩니다. 예를 들어,
A\B\C;
사용 후new C()
와 같은 사용법은A\B\C()
이름으로 확인됩니다. 마찬가지로,A\B\fn;
함수를 사용한 후fn()
과 같은 사용법은A\B\fn
이라는 이름으로 확인됩니다. - 규정되지 않은 이름의 경우 가져오기 규칙이 적용되지 않고 이름이 클래스와 유사한 기호를 참조하는 경우 현재 네임스페이스가 앞에 추가됩니다. 예를 들어 네임스페이스
A\B
내의new C()
는A\B\C
이름으로 확인됩니다. - 정규화되지 않은 이름의 경우 가져오기 규칙이 적용되지 않고 이름이 함수 또는 상수를 참조하고 코드가 전역 네임스페이스 외부에 있는 경우 런타임에 이름이 확인됩니다. 코드가 네임스페이스
A\B
에 있다고 가정하고foo()
함수에 대한 호출을 해결하는 방법은 다음과 같습니다.- 현재 네임스페이스에서 함수를 찾습니다:
A\B\foo()
. - 전역 함수
foo()
를 찾아서 호출하려고 합니다.
- 현재 네임스페이스에서 함수를 찾습니다:
예제 #1 설명된 이름 확인
<?php
namespace A;
use B\D, C\E as F;
// function calls
foo(); // first tries to call "foo" defined in namespace "A"
// then calls global function "foo"
\foo(); // calls function "foo" defined in global scope
my\foo(); // calls function "foo" defined in namespace "A\my"
F(); // first tries to call "F" defined in namespace "A"
// then calls global function "F"
// class references
new B(); // creates object of class "B" defined in namespace "A"
// if not found, it tries to autoload class "A\B"
new D(); // using import rules, creates object of class "D" defined in namespace "B"
// if not found, it tries to autoload class "B\D"
new F(); // using import rules, creates object of class "E" defined in namespace "C"
// if not found, it tries to autoload class "C\E"
new \B(); // creates object of class "B" defined in global scope
// if not found, it tries to autoload class "B"
new \D(); // creates object of class "D" defined in global scope
// if not found, it tries to autoload class "D"
new \F(); // creates object of class "F" defined in global scope
// if not found, it tries to autoload class "F"
// static methods/namespace functions from another namespace
B\foo(); // calls function "foo" from namespace "A\B"
B::foo(); // calls method "foo" of class "B" defined in namespace "A"
// if class "A\B" not found, it tries to autoload class "A\B"
D::foo(); // using import rules, calls method "foo" of class "D" defined in namespace "B"
// if class "B\D" not found, it tries to autoload class "B\D"
\B\foo(); // calls function "foo" from namespace "B"
\B::foo(); // calls method "foo" of class "B" from global scope
// if class "B" not found, it tries to autoload class "B"
// static methods/namespace functions of current namespace
A\B::foo(); // calls method "foo" of class "B" from namespace "A\A"
// if class "A\A\B" not found, it tries to autoload class "A\A\B"
\A\B::foo(); // calls method "foo" of class "B" from namespace "A"
// if class "A\B" not found, it tries to autoload class "A\B"
?>