광범위하게 말하면 네임스페이스는 사물을 캡슐화하는 방법입니다. 이 추상적인 개념은 여러 곳에서 찾아볼 수 있습니다. 예를 들어 디렉터리는 운영 체제에서 관련 파일을 그룹화하는 데 사용되며 디렉터리에 있는 파일의 네임스페이스 역할을 합니다. 이 원리를 프로그래밍 분야에 적용하면 네임스페이스 개념이 나옵니다
PHP에서 네임스페이스는 클래스 라이브러리나 애플리케이션을 작성할 때 클래스나 함수와 같은 재사용 가능한 코드를 만들 때 발생하는 두 가지 유형의 문제를 해결하는 데 사용됩니다. 하나는 사용자가 작성한 코드와 PHP 내부 클래스/함수/상수 간의 이름 충돌입니다. 타사 클래스/함수/상수; 다른 하나는 매우 긴 식별자 이름(일반적으로 첫 번째 유형의 문제를 완화하기 위해 정의됨)에 대한 별칭(또는 짧은) 이름을 생성하여 소스 코드의 가독성을 향상시킵니다. PHP 네임스페이스는 관련 클래스, 함수 및 상수를 그룹화하는 방법을 제공합니다. 이번 글에서는 PHP 네임스페이스를 자세히 소개하겠습니다
모든 합법적인 PHP 코드가 네임스페이스에 포함될 수 있지만 클래스(추상 클래스 및 특성 포함), 인터페이스, 함수 및 상수와 같은 유형의 코드만 네임스페이스의 영향을 받습니다.
네임스페이스는 키워드 네임스페이스를 사용하여 선언됩니다. 파일에 네임스페이스가 포함된 경우 다음을 제외한 다른 모든 코드보다 먼저 네임스페이스를 선언해야 합니다. 키워드 선언
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
하위 네임스페이스
디렉터리와 파일 간의 관계와 마찬가지로 PHP 네임스페이스를 사용하면 계층적 네임스페이스 이름을 지정할 수도 있습니다. 따라서 네임스페이스 이름은 계층적 방식으로 정의될 수 있습니다
<?<span style="color: #000000;">php namespace MyProject\Sub\Level; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
<?<span style="color: #000000;">php namespace MyProject\Sub\Level; </span><span style="color: #0000ff;">const</span> NUM = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">echo</span> NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> <span style="color: #0000ff;">echo</span> \MyProject\Sub\Level\NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> ?>
동일한 파일에 여러 네임스페이스를 정의할 수 있습니다. 동일한 파일에 여러 네임스페이스를 정의하는 데는 두 가지 구문 형식이 있습니다.
실제 프로그래밍 실습에서는 동일한 파일에 여러 네임스페이스를 정의하는 것을 매우 권장하지 않습니다. 이 방법은 주로 여러 PHP 스크립트를 동일한 파일로 병합하는 데 사용됩니다
【1】간단한 조합 구문(권장하지 않음)
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } namespace AnotherProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
【2】중괄호 구문
<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } namespace AnotherProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } </span>?>
<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> NUM = 1<span style="color: #000000;">; } namespace AnotherProject { </span><span style="color: #0000ff;">const</span> NUM = 2<span style="color: #000000;">; </span><span style="color: #0000ff;">echo</span> NUM;<span style="color: #008000;">//</span><span style="color: #008000;">2</span> <span style="color: #0000ff;">echo</span> \MyProject\NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> <span style="color: #000000;">} </span>?>
글로벌
네임스페이스가 아닌 전역 코드를 네임스페이스 코드와 결합하려면 중괄호 구문만 사용할 수 있습니다. 전역 코드는 이름 없는 네임스페이스 문과 함께 중괄호로 묶어야 합니다.
<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } namespace { </span><span style="color: #008000;">//</span><span style="color: #008000;"> global code</span> <span style="color: #008080;">session_start</span><span style="color: #000000;">(); </span><span style="color: #800080;">$a</span> =<span style="color: #000000;"> MyProject\connect(); </span><span style="color: #0000ff;">echo</span> MyProject\Connection::<span style="color: #000000;">start(); } </span>?>
정규화되지 않은 이름은 Foo와 같이 이름에 네임스페이스 구분 기호가 포함되지 않은 식별자를 나타냅니다.
정규화된 이름은 FooBar와 같이 이름에 네임스페이스 구분 기호가 포함된 식별자를 나타냅니다
정규화된 이름은 이름에 네임스페이스 구분 기호가 포함되어 있고 FooBar와 같이 네임스페이스 구분 기호로 시작하는 식별자를 나타냅니다. 네임스페이스Foo는 정규화된 이름이기도 합니다
요소에 동적으로 액세스하려면(예: 변수 함수) 정규화된 이름을 사용해야 합니다.
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } </span><span style="color: #800080;">$var1</span> = 'test'<span style="color: #000000;">; </span><span style="color: #800080;">$var2</span> = '\MyProject\test'<span style="color: #000000;">; </span><span style="color: #800080;">$var1</span>();<span style="color: #008000;">//</span><span style="color: #008000;">报错</span> <span style="color: #800080;">$var2</span>();/111 ?>
PHP는 현재 네임스페이스의 내부 요소에 액세스하는 두 가지 추상 방법인 __NAMESPACE__ 매직 상수와 네임스페이스 키워드를 지원합니다.
__NAMESPACE__ 상수의 값은 현재 네임스페이스의 이름을 포함하는 문자열입니다. 어떤 네임스페이스에도 포함되지 않은 전역 코드에는 빈 문자열
이 포함되어 있습니다.<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } </span><span style="color: #800080;">$var</span> = __NAMESPACE__.'\test'<span style="color: #000000;">; </span><span style="color: #800080;">$var</span>();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
키워드 네임스페이스를 사용하면 현재 네임스페이스나 하위 네임스페이스의 요소에 명시적으로 액세스할 수 있습니다.
클래스의 self 연산자와 동일합니다.<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } test();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> __NAMESPACE__.test();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> namespace\test();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
네임스페이스가 정의되지 않으면 PHP가 네임스페이스 개념을 도입하기 전과 마찬가지로 모든 클래스와 함수가 전역 공간에 정의됩니다. 이름 앞에 붙는 것은 이름이 다른 네임스페이스에 있더라도 이름이 전역 공간에 있음을 나타냅니다
<?<span style="color: #000000;">php namespace A\B\C; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> 这个函数是 A\B\C\fopen </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">fopen</span><span style="color: #000000;">() { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span> <span style="color: #800080;">$f</span> = \<span style="color: #008080;">fopen</span>(...); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局的fopen函数</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">$f</span><span style="color: #000000;">; } </span>?>
php允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类unix文件系统中可以创建对其它的文件或目录的符号连接
所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名
在PHP中,别名是通过操作符 use 来实现的
别名
<?<span style="color: #000000;">php namespace hello\world\test; </span><span style="color: #0000ff;">use</span> hello\world\test <span style="color: #0000ff;">as</span> t;<span style="color: #008000;">//</span><span style="color: #008000;">用t来替代hello\world\test</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> demo(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } t\demo();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
as可以省略
<?<span style="color: #000000;">php namespace hello\world\test; </span><span style="color: #0000ff;">use</span> hello\world\test;<span style="color: #008000;">//</span><span style="color: #008000;">用test来替代hello\world\test</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> demo(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } test\demo();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
导入
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span><span style="color: #000000;"> \ArrayObject; </span><span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> ArrayObject([]);<span style="color: #008000;">//</span><span style="color: #008000;">若不使用"use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象</span> ?>
为了简化,一行中可以包含多个use语句
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span> Another,<span style="color: #000000;"> My\Full\NSname; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 My\Full\Classname 对象</span> NSname\subns\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用函数 My\Full\NSname\subns\func</span> ?>