작성: 2008.08.11
이름지정규칙(Name resolution rules)
네임스페이스 지원으로 이름(클래스명, 함수명 등)은 동일하지만 서로 다른 네임스페이스에 소속될 수 있기 때문에 각 이름이 소속된 네임스페이스를 명확히 지정할 필요가 있습니다. 이름을 지정하는 방법으로는 크게 4가지로 나눌 수 있습니다.
▶ 다른 네임스페이스에 있는 이름을 참조할 때는 Fully Qualified Name 사용
▶ 현재 네임스페이스에 있는 이름을 참조할 때는 Unqualified Name 사용
▶ use 연산자를 이용하여 다른 네임스페이스를 현재 네임스페이스로 가져옴(import)
▶ 전역 네임스페이스에 있는 이름을 참조할 때는 네임스페이스 이름없이 :: 연산자로 시작함
Fully Qualified Name은 네임스페이스의 완전한 이름으로 아래의 예에서 볼 때 MyProject::Connection::NS_CONST, MyProject::Connection::my_function을 의미합니다.
[code php;gutter:true]
<?php
namespace MyProject::Connection;
const NS_CONST = 'namespace constant NS_CONST';
function my_function() {
print "namespace function my_function()\n";
}
print MyProject::Connection::NS_CONST . "\n";
MyProject::Connection::my_function();
?>
[/code]
다른 네임스페이스에 있는 이름을 참조할 때는 완전한 네임스페이스 이름을 가진 Fully Qualified Name을 사용하여야 하나 현재 네임스페이스에 있는 이름을 참조할 때는 네임스페이스 이름을 생략한 Unqualified Name을 사용할 수 있습니다. 위의 예에서 10, 11번행의 현재 네임스페이스가 MyProject::Connection이므로 아래와 같이 Fully Qualified Name 대신에 Unqualified Name을 사용할 수 있습니다.
[code php;gutter:false]
print NS_CONST . "\n";
my_function();
[/code]
전역 네임스페이스(global namespace)는 그 이름을 가지고 있지 않으므로 네임스페이스 이름을 지정할 수 없습니다. 이런 이유로 전역 네임스페이스에 소속된 이름을 참조할 때는 네임스페이스 이름없이 :: 연산자로 시작하는 이름을 사용합니다.
[code php;gutter:false]
<?php
namespace A::B::C;
/* This function is A::B::C::fopen */
function fopen() {
/* ... */
$f = ::fopen(...); // call global fopen
return $f;
}
?>
[/code]
use 연산자를 이용하면 스크립트 실행시 다른 네임스페이스를 현재 네임스페이스로 임포트할 수 있습니다. 따라서 소스를 작성하거나 보기에 불편한 긴 Fully Qualified Name 대신에 짧은 별명(alias)을 사용할 수 있습니다. PHP에서 벤치마킹한 것으로 보이는 C++에서는 짧은 이름을 사용하기 위한 방법으로 별명을 이용하는 것 말고도 using 지시자(directive)와 using 선언자(declaration)를 이용하는 방법이 있습니다만 PHP에서는 이러한 방법까지는 제공하지 않습니다.
[code php;gutter:false]
<?php
namespace MyProject::Connection;
function my_class() { /* code */ }
?>
[/code]
< inc.php >
[code php;gutter:false]
<?php
require_once('inc.php');
use MyProject::Connection as Connection;
$my = new Connection::my_class();
?>
[/code]
Unqualified 함수 호출
네임스페이스 내에서 Unqualified 함수를 호출하면 아래와 같은 규칙에 따라 해당 함수를 호출합니다.
① 현재 네임스페이스에 정의된 함수를 호출
② PHP 내장(internal; built-in) 함수를 호출
[code php;gutter:true]
<?php
namespace A::B;
$a = ucfirst("testing 'name resolution rules'");
echo($a);
function ucfirst($str) {
return '<span style="font-size:32pt;color:steelblue">'
. ::ucfirst(substr($str, 0, 1))
. '</span>'
. substr($str, 1);
}
?>
[/code]
위 소스의 4번행을 실행하면 7번행에 정의된 현재 네임스페이스의 ucfirst 함수를 호출합니다. 따라서 위 소스를 실행하면 아래와 같은 결과를 얻을 수 있습니다.
Testing 'name resolution rules'
만약 7번행부터 12번행에서와 같이 현재 네임스페이스에 정의된 ucfirst() 함수가 없었다면 PHP 내장함수인 ucfirst()를 바로 호출하였을 것이고 그 결과는 아래와 같았을 것입니다.
Testing 'name resolution rules'
Unqualified 클래스 호출
현재 네임스페이스가 A::B::C일 때, new C()는 A::B::C()로 변환됩니다. 현재 네임스페이스가 A::B일 때, new C()의 호출은 아래와 같은 규칙에 따릅니다.
① 네임스페이스 A::B 내에 정의된 클래스 C에 대한 객체 생성
② PHP 내장(internal; built-in) 클래스에 대한 객체 생성
Qualified 함수 호출
A::B::foo() 함수의 호출은 아래와 같은 규칙에 따릅니다.
① 네임스페이스 A::B 내에 정의된 함수 foo()를 호출
② 클래스 A::B의 정적 멤버 함수 foo()를 호출
[code php;gutter:false]
<?php
namespace A;
// static methods/namespace functions of current namespace
A::foo(); // first tries to call function "foo" from namespace "A::A"
// then tries to call method "foo" of class "A" from namespace "A"
// then tries to call function "foo" from namespace "A"
// then calls method "foo" of internal class "A"
?>
[/code]
< 출처:php.net >
Qualified 클래스 호출
new A::B::C()는 네임스페이스 A::B의 클래스 C를 참조합니다.