FAQ: 네임스페이스에 대해 알아야 할 사항

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

이 FAQ는 일반적인 질문과 완전히 이해하는 데 도움이 되는 몇 가지 구현 세부 사항의 두 섹션으로 나뉩니다.

먼저 일반적인 질문입니다.

  1. 네임스페이스를 사용하지 않는 경우 이 중 하나라도 신경써야 합니까?
  2. 네임스페이스에서 내부 또는 전역 클래스를 어떻게 사용합니까?
  3. 네임스페이스 클래스 함수 또는 자체 네임스페이스의 상수를 어떻게 사용합니까?
  4. \my\name 또는 \name과 같은 이름은 어떻게 확인됩니까?
  5. my\name과 같은 이름은 어떻게 확인됩니까?
  6. 이름과 같은 정규화되지 않은 클래스 name은 어떻게 확인됩니까?
  7. 정규화되지 않은 함수 이름 또는 이름과 같은 정규화되지 않은 상수 이름은 어떻게 확인됩니까?

이해하는 데 도움이 되는 네임스페이스 구현에 대한 몇 가지 구현 세부 정보가 있습니다.

  1. 가져오기 이름은 동일한 파일에 정의된 클래스와 충돌하지 않아야 합니다.
  2. 중첩된 네임스페이스는 허용되지 않습니다.
  3. 동적 네임스페이스 이름(따옴표 붙은 식별자)은 백슬래시를 이스케이프해야 합니다.
  4. 치명적인 오류가 있는 백슬래시 다이를 사용하여 참조되는 정의되지 않은 상수
  5. 특수 상수 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\namemy에 적용됩니다.

그렇지 않으면 현재 네임스페이스 이름이 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.
?>