FAQ: 네임스페이스에 대해 알아야 할 사항
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
이 FAQ는 일반적인 질문과 완전히 이해하는 데 도움이 되는 몇 가지 구현 세부 사항의 두 섹션으로 나뉩니다.
먼저 일반적인 질문입니다.
- 네임스페이스를 사용하지 않는 경우 이 중 하나라도 신경써야 합니까?
- 네임스페이스에서 내부 또는 전역 클래스를 어떻게 사용합니까?
- 네임스페이스 클래스 함수 또는 자체 네임스페이스의 상수를 어떻게 사용합니까?
\my\name
또는\name
과 같은 이름은 어떻게 확인됩니까?my\name
과 같은 이름은 어떻게 확인됩니까?- 이름과 같은 정규화되지 않은 클래스
name
은 어떻게 확인됩니까? - 정규화되지 않은 함수 이름 또는 이름과 같은 정규화되지 않은 상수 이름은 어떻게 확인됩니까?
이해하는 데 도움이 되는 네임스페이스 구현에 대한 몇 가지 구현 세부 정보가 있습니다.
- 가져오기 이름은 동일한 파일에 정의된 클래스와 충돌하지 않아야 합니다.
- 중첩된 네임스페이스는 허용되지 않습니다.
- 동적 네임스페이스 이름(따옴표 붙은 식별자)은 백슬래시를 이스케이프해야 합니다.
- 치명적인 오류가 있는 백슬래시 다이를 사용하여 참조되는 정의되지 않은 상수
- 특수 상수 NULL, TRUE, FALSE, ZEND_THREAD_SAFE 또는 ZEND_DEBUG_BUILD를 재정의할 수 없습니다.
네임스페이스를 사용하지 않는 경우 이 중 하나라도 신경써야 합니까?
아니요. 네임스페이스는 기존 코드나 네임스페이스를 포함하지 않는 아직 작성되지 않은 코드에 영향을 미치지 않습니다. 원하는 경우 이 코드를 작성할 수 있습니다.
예제 #1 네임스페이스 외부의 전역 클래스 액세스
<?php
$a = new \stdClass;
?>
이것은 기능적으로 다음과 동일합니다.
예제 #2 네임스페이스 외부의 전역 클래스 액세스
<?php
$a = new stdClass;
?>
네임스페이스에서 내부 또는 전역 클래스를 어떻게 사용합니까?
예제 #3 네임스페이스의 내부 클래스 액세스
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $parameter_type_example = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// extending an internal or global class
class MyException extends \Exception {}
?>
고유한 네임스페이스에서 네임스페이스 클래스, 함수 또는 상수를 사용하려면 어떻게 해야 합니까?
예제 #4 네임스페이스의 내부 클래스, 함수 또는 상수 액세스
<?php
namespace foo;
class MyClass {}
// using a class from the current namespace as a parameter type
function test(MyClass $parameter_type_example = null) {}
// another way to use a class from the current namespace as a parameter type
function test(\foo\MyClass $parameter_type_example = null) {}
// extending a class from the current namespace
class Extended extends MyClass {}
// accessing a global function
$a = \globalfunc();
// accessing a global constant
$b = \INI_ALL;
?>
\my\name
또는 \name
과 같은 이름은 어떻게 확인됩니까?
\
로 시작하는 이름은 항상 모양으로 해석되므로 \my\name
은 사실 my\name
이고 \Exception
은 예외입니다.
예제 #5 네임스페이스의 내부 클래스, 함수 또는 상수 액세스
<?php
namespace foo;
$a = new \my\name(); // instantiates "my\name" class
echo \strlen('hi'); // calls function "strlen"
$a = \INI_ALL; // $a is set to the value of constant "INI_ALL"
?>
my\name
과 같은 이름은 어떻게 확인됩니까?
백슬래시를 포함하지만 my\name
과 같이 백슬래시로 시작하지 않는 이름은 두 가지 방법으로 확인할 수 있습니다.
my
에 다른 이름의 별칭을 지정하는 가져오기 문이 있으면 가져오기 별칭이 my\name
의 my
에 적용됩니다.
그렇지 않으면 현재 네임스페이스 이름이 my\name
앞에 추가됩니다.
예제 #6 Qualified names
<?php
namespace foo;
use blah\blah as foo;
$a = new my\name(); // instantiates "foo\my\name" class
foo\bar::name(); // calls static method "name" in class "blah\blah\bar"
my\bar(); // calls function "foo\my\bar"
$a = my\BAR; // sets $a to the value of constant "foo\my\BAR"
?>
name
과 같은 정규화되지 않은 클래스 이름은 어떻게 확인됩니까?
name
과 같이 백슬래시가 포함되지 않은 클래스 이름은 두 가지 방법으로 확인할 수 있습니다.
name
에 다른 이름의 별칭을 지정하는 가져오기 문이 있는 경우 가져오기 별칭이 적용됩니다.
그렇지 않으면 현재 네임스페이스 이름이 name
앞에 추가됩니다.
예제 #7 Unqualified class names
<?php
namespace foo;
use blah\blah as foo;
$a = new name(); // instantiates "foo\name" class
foo::name(); // calls static method "name" in class "blah\blah"
?>
정규화되지 않은 함수 이름 또는 이름과 같은 정규화되지 않은 상수 name
은 어떻게 확인됩니까?
name
과 같이 백슬래시를 포함하지 않는 함수 또는 상수 이름은 2가지 다른 방법으로 해결할 수 있습니다.
먼저 현재 네임스페이스 이름이 name
앞에 추가됩니다.
마지막으로 현재 네임스페이스에 상수 또는 함수 name
이 존재하지 않는 경우 전역 상수 또는 함수 name
이 있으면 사용합니다.
예제 #8 규정되지 않은 함수 또는 상수 이름
<?php
namespace foo;
use blah\blah as foo;
const FOO = 1;
function my() {}
function foo() {}
function sort(&$a)
{
\sort($a); // calls the global function "sort"
$a = array_flip($a);
return $a;
}
my(); // calls "foo\my"
$a = strlen('hi'); // calls global function "strlen" because "foo\strlen" does not exist
$arr = array(1,3,2);
$b = sort($arr); // calls function "foo\sort"
$c = foo(); // calls function "foo\foo" - import is not applied
$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied
$b = INI_ALL; // sets $b to value of global constant "INI_ALL"
?>
가져오기 이름은 동일한 파일에 정의된 클래스와 충돌하지 않아야 합니다.
다음 스크립트 조합은 유효합니다.
file1.php
<?php
namespace my\stuff;
class MyClass {}
?>
another.php
<?php
namespace another;
class thing {}
?>
file2.php
<?php
namespace my\stuff;
include 'file1.php';
include 'another.php';
use another\thing as MyClass;
$a = new MyClass; // instantiates class "thing" from namespace another
?>
MyClass 정의가 별도의 파일에 있기 때문에 MyClass
클래스가 my\stuff
네임스페이스 내에 존재하더라도 이름 충돌은 없습니다. 그러나 다음 예제에서는 MyClass가 use 문과 동일한 파일에 정의되어 있기 때문에 이름 충돌 시 치명적인 오류가 발생합니다.
<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // fatal error: MyClass conflicts with import statement
$a = new MyClass;
?>
중첩된 네임스페이스는 허용되지 않습니다.
PHP는 네임스페이스 중첩을 허용하지 않습니다.
<?php
namespace my\stuff {
namespace nested {
class foo {}
}
}
?>
그러나 다음과 같이 중첩된 네임스페이스를 시뮬레이션하는 것은 쉽습니다.
<?php
namespace my\stuff\nested {
class foo {}
}
?>
동적 네임스페이스 이름(따옴표 붙은 식별자)은 백슬래시를 이스케이프해야 합니다.
백슬래시는 문자열 내에서 이스케이프 문자로 사용되기 때문에 문자열 내에서 사용할 때는 항상 두 배로 사용해야 한다는 사실을 깨닫는 것이 매우 중요합니다. 그렇지 않으면 의도하지 않은 결과가 발생할 위험이 있습니다.
예제 #9 큰 따옴표로 묶인 문자열 안에 네임스페이스 이름을 사용하는 것의 위험
<?php
$a = "dangerous\name"; // \n is a newline inside double quoted strings!
$obj = new $a;
$a = 'not\at\all\dangerous'; // no problems here.
$obj = new $a;
?>
작은 따옴표로 묶인 문자열 내에서 백슬래시 이스케이프 시퀀스를 사용하는 것이 훨씬 더 안전하지만 모범 사례로 모든 문자열에서 백슬래시를 이스케이프하는 것이 여전히 권장됩니다.
치명적인 오류가 있는 백슬래시 다이를 사용하여 참조되는 정의되지 않은 상수
FOO
와 같이 규정되지 않은 정의되지 않은 상수는 PHP가 FOO
가 상수의 값이라고 가정했음을 설명하는 알림을 생성합니다. 백슬래시가 포함된 정규화된 상수 또는 정규화된 모든 상수를 찾지 못하면 치명적인 오류가 발생합니다.
예제 #10 정의되지 않은 상수
<?php
namespace bar;
$a = FOO; // produces notice - undefined constants "FOO" assumed "FOO";
$a = \FOO; // fatal error, undefined namespace constant FOO
$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO
$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO
?>
특수 상수 NULL, TRUE, FALSE, ZEND_THREAD_SAFE 또는 ZEND_DEBUG_BUILD를 재정의할 수 없습니다.
특별한 내장 상수인 네임스페이스 상수를 정의하려고 하면 치명적인 오류가 발생합니다.
예제 #11 정의되지 않은 상수
<?php
namespace bar;
const NULL = 0; // fatal error;
const true = 'stupid'; // also fatal error;
// etc.
?>