네임스페이스란 무엇입니까? 이 글이 여러분에게 PHP의 네임스페이스에 대한 심층적인 이해를 제공할 것입니다. 여러분에게 도움이 되기를 바랍니다.
네임스페이스란 무엇인가요?
넓은 의미에서 네임스페이스는 사물을 캡슐화하는 방식이며 이러한 추상적인 개념은 여러 곳에서 볼 수 있습니다. 예를 들어 디렉터리는 운영 체제에서 관련 파일을 그룹화하는 데 사용되며 디렉터리에 있는 파일의 네임스페이스 역할을 합니다.
간단한 예로 foo.txt 파일은 /home/greg와 /home/other 디렉터리에 동시에 존재할 수 있지만, 두 개의 foo.txt 파일이 같은 디렉터리에 존재할 수는 없습니다. 또한 /home/greg 디렉토리 외부의 foo.txt 파일에 액세스할 때 파일 이름 앞에 디렉토리 이름과 디렉토리 구분 기호를 넣어야 합니다(예: /home/greg/foo.txt). 이 원칙을 프로그래밍 분야에 적용한 것이 네임스페이스의 개념입니다.
네임스페이스 정의
PHP의 네임스페이스는 PHP5.3에 추가되었습니다. C++를 알고 있다면 네임스페이스는 새로운 것이 아닙니다. 그러나 네임스페이스는 PHP에서 여전히 매우 중요합니다.
PHP 네임스페이스는 다음 두 가지 유형의 문제를 해결할 수 있습니다.
사용자 및 PHP 내부 클래스/함수/상수 또는 타사 클래스/함수/상수에 의해 작성된 코드
소스 코드 가독성을 높이기 위해 매우 긴 식별자 이름(일반적으로 첫 번째 유형의 문제를 완화하기 위해 정의됨)에 대한 별칭(또는 짧은) 이름을 만듭니다.
1) 네임스페이스 정의(네임스페이스 키워드 사용)
적법한 모든 PHP 코드가 네임스페이스에 포함될 수 있지만 클래스( 추상 클래스 및 특성 포함), 인터페이스, 함수 및 상수는 네임스페이스의 영향을 받습니다.
네임스페이스 정의는 키워드 네임스페이스를 통해 선언해야 합니다. 구문 형식은 다음과 같습니다.
namespace 命名空间名;
[예] 네임스페이스를 정의하는 방법을 보여드리겠습니다.
<?php namespace MyProject; // 定义名为 MyProject 的命名空间。 const CONNECT_OK = 1; class Myclass { /* ... */ } function Myfunc() { /* ... */ } ?>
네임스페이스를 선언하기 전에 소스 파일 인코딩을 정의하는 데 사용되는 선언문을 제외하고 PHP가 아닌 모든 코드(공백 문자 포함)는 네임스페이스 선언 앞에 나타날 수 없습니다.
또한 PHP의 다른 언어 기능과 달리 동일한 네임스페이스를 여러 파일에 정의할 수 있어 동일한 네임스페이스의 내용을 나누어 다른 파일에 저장할 수 있습니다.
2) 하위 네임스페이스 정의
는 디렉토리 및 파일과 매우 유사하며, PHP의 네임스페이스에서는 계층적 네임스페이스 이름을 지정할 수도 있습니다. 따라서 네임스페이스 이름을 계층적으로 정의할 수 있습니다:
namespace App\Model; namespace App\Controller\Home;
[예] 하위 네임스페이스 정의:
<?php namespace MyProject\Controller\Home; // 定义名为 MyProject 的命名空间。 const CONNECT_OK = 1; class Myclass { /* ... */ } function Myfunc() { /* ... */ } ?>
3) 동일한 파일에 여러 이름 정의 네임스페이스
동일한 파일에 여러 네임스페이스를 정의할 수도 있습니다. 다음은 설명하기 위한 예입니다. ] 여러 네임스페이스를 정의합니다 - 간단한 조합 구문입니다.
<?php namespace MyProject; const CONNECT_OK = 1; class className { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class className { /* ... */ } ?>
[예] 여러 네임스페이스를 정의합니다 - 중괄호 { } 구문.
<?php namespace MyProject{ const CONNECT_OK = 1; class className { /* ... */ } } namespace AnotherProject{ const CONNECT_OK = 1; class className { /* ... */ } } ?>
실제 프로그래밍 실습에서는 동일한 파일에 여러 네임스페이스를 정의하는 것은 권장되지 않습니다. 여러 네임스페이스를 정의하는 것은 주로 동일한 파일에 여러 PHP 스크립트를 결합하는 데 사용됩니다. 여러 네임스페이스를 정의할 때는 중괄호 구문을 사용하는 것이 좋습니다.
네임스페이스가 아닌 전역의 코드와 네임스페이스의 코드를 결합하려면 중괄호 형식의 구문만 사용할 수 있습니다. 동시에 전역 코드는 이름이 지정되지 않은 네임스페이스 문과 함께 사용해야 합니다.
<?php namespace MyProject{ // 命名空间中的代码 const CONNECT_OK = 1; class className { /* ... */ } } namespace { // 命名空间外的全局代码 $obj = new MyProject\className(); } ?>
네임스페이스 사용: 기본네임스페이스 사용 방법을 논의하기 전에 먼저 다음을 이해하는 것이 중요합니다. PHP 요소에 사용할 네임스페이스를 파악합니다. PHP 네임스페이스와 파일 시스템을 간단하게 비유할 수 있습니다. 파일 시스템의 파일에 액세스하는 방법에는 세 가지가 있습니다.
限定名称,或包含前缀的名称,例如$a = new subnamespace\foo();
或subnamespace\foo::staticmethod();
。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为 subnamespace\foo。
完全限定名称,或包含了全局前缀操作符的名称,例如$a = new \currentnamespace\foo();
或\currentnamespace\foo::staticmethod();
。在这种情况下,foo 总是被解析为代码中的文字名 currentnamespace\foo。
警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
下面是一个使用这三种方式的实例,我们需要两个 PHP 源文件,分别是 demo.php 和 index.php,示例代码如下:
1) demo.php
<?php namespace Foo\Bar\Demo; const FOO = 1; function foo() {} class foo { public function demo() { echo '命名空间为:Foo\Bar\Demo'; } } ?>
2) index.php
<?php namespace Foo\Bar; include 'Demo.php'; const FOO = 2; function foo() { echo 'Foo\Bar 命名空间下的 foo 函数<br>'; } class foo { static function demo(){ echo '命名空间为:Foo\Bar<br>'; } } /* 非限定名称 */ foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo foo::demo(); // 解析为类 Foo\Bar\foo 的静态方法 staticmethod。 echo FOO.'<br>'; // 解析为常量 Foo\Bar\FOO /* 限定名称 */ Demo\foo(); // 解析为函数 Foo\Bar\Demo\foo Demo\foo::demo(); // 解析为类 Foo\Bar\Demo\foo, // 以及类的方法 demo echo Demo\FOO.'<br>'; // 解析为常量 Foo\Bar\Demo\FOO /* 完全限定名称 */ \Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo \Foo\Bar\foo::demo(); // 解析为类 Foo\Bar\foo, 以及类的方法 demo echo \Foo\Bar\FOO.'<br>'; // 解析为常量 Foo\Bar\FOO ?>
运行结果如下:
Foo\Bar 命名空间下的 foo 函数 命名空间为:Foo\Bar 2 Foo\Bar\Demo 命名空间下的 foo 函数 命名空间为:Foo\Bar\Demo 1 Foo\Bar 命名空间下的 foo 函数 命名空间为:Foo\Bar 2
注意:访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 等。
使用命名空间:别名/导入
PHP 允许通过别名引用或导入的方式来使用外部的命名空间,这是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。
使用 use 关键字可以实现命名空间的导入,从 PHP5.6 开始允许导入函数和常量,并为它们设置别名。语法格式如下:
use namespace;
在 PHP 中,别名是通过操作符 use 与 as 来实现的,语法格式如下:
use 命名空间 as 别名;
【示例】使用 use 操作符导入和使用别名。
<?php namespace foo; use My\Full\Classname as Another; // 下面的例子与 use My\Full\NSname as NSname 相同 use My\Full\NSname; // 导入一个全局类 use ArrayObject; // 导入一个函数 use function My\Full\functionName; // 导入一个函数并定义别名 use function My\Full\functionName as func; // 导入一个常量 use const My\Full\CONSTANT; $obj = new namespace\Another; // 实例化 foo\Another 对象 $obj = new Another; // 实例化 My\Full\Classname 对象 NSname\subns\func(); // 调用 My\Full\NSname\subns\func 函数 $a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象 // 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象 func(); // 调用 My\Full\functionName 函数 echo CONSTANT; // 打印 My\Full\CONSTANT 常量 ?>
注意:对命名空间中的名称(包含命名空间分隔符的完全限定名称,如 Foo\Bar ,以及相对的不包含命名空间分隔符的全局名称,如 FooBar)来说,前导的反斜杠是不必要的也是不推荐的,因为导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析。
为了简化操作,PHP 还支持在一行中导入多个命名空间,中间使用,隔开,示例代码如下:
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 实例化 My\Full\Classname 对象 NSname\subns\func(); // 调用 My\Full\NSname\subns\func 函数 ?>
导入操作是编译执行的,但动态的类名称、函数名称或常量名称则不是。
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // 实例化一个 My\Full\Classname 对象 $a = 'Another'; $obj = new $a; // 实际化一个 Another 对象 ?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
namespace 关键字和 __NAMESPACE__ 常量
PHP 支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和 namespace 关键字。
__NAMESPACE__ 常量的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它是一个空的字符串。示例代码如下:
<?php namespace App\Controller\Home; echo __NAMESPACE__; ?>
运行结果如下:
App\Controller\Home
namespace 关键字可用来显式访问当前命名空间或子命名空间中的元素,它等价于类中的 self 操作符。示例代码如下:
<?php namespace MyProject; use Foo\Bar\Demo as demo; // 导入 Foo\Bar\Demo 命名空间 blah\mine(); // 调用 MyProject\blah\mine() 函数 namespace\blah\mine(); // 调用 MyProject\blah\mine() 函数 namespace\func(); // 调用 MyProject\func() 函数 namespace\sub\func(); // 调用 MyProject\sub\func() 函数 namespace\cname::method(); // 调用 MyProject\cname 类的静态方法 method $a = new namespace\sub\cname(); // 实例化 MyProject\sub\cname 对象 $b = namespace\CONSTANT; // 将常量 MyProject\CONSTANT 的值赋给 $b ?>
命名空间名称解析规则
在说明名称解析规则之前,我们先来看看命名空间名称的定义:
非限定名称:名称中不包含命名空间分隔符的标识符,例如 Foo;
限定名称:名称中含有命名空间分隔符的标识符,例如 Foo\Bar;
完全限定名称:名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,例如 \Foo\Bar。namespace\Foo 也是一个完全限定名称。
名称解析遵循下列规则:
현재 네임스페이스에서 ABfoo()라는 함수를 검색합니다.
해 보세요. 전역 공간에서 foo() 함수를 찾고 호출합니다.
new C() 구문 분석:
new DE() 구문 분석:
글로벌 네임스페이스에서 글로벌 클래스를 참조하려면 정규화된 이름인 new C()를 사용해야 합니다.
추천 학습: "PHP 비디오 튜토리얼"
위 내용은 네임스페이스란 무엇입니까? PHP의 네임스페이스에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!