>  기사  >  백엔드 개발  >  네임스페이스란 무엇입니까? PHP의 네임스페이스에 대한 자세한 설명

네임스페이스란 무엇입니까? PHP의 네임스페이스에 대한 자세한 설명

怪我咯
怪我咯앞으로
2017-06-14 11:49:586006검색

네임스페이스란 무엇입니까? 이 글이 여러분에게 PHP의 네임스페이스에 대한 심층적인 이해를 제공할 것입니다. 여러분에게 도움이 되기를 바랍니다.

네임스페이스란 무엇입니까? 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 네임스페이스와 파일 시스템을 간단하게 비유할 수 있습니다. 파일 시스템의 파일에 액세스하는 방법에는 세 가지가 있습니다.

    foo.txt와 같은 상대 파일 이름 형식. currentdirectory/foo.txt로 구문 분석됩니다. 여기서 currentdirectory는 현재 디렉터리를 나타냅니다. 따라서 현재 디렉터리가 /home/foo인 경우 파일 이름은 /home/foo/foo.txt로 구문 분석됩니다.
  • 상대 경로 이름 형식은 하위 디렉터리/foo와 같습니다. .txt. currentdirectory/subdirectory/foo.txt로 구문 분석됩니다.
  • 절대 경로 이름 형식은 /main/foo.txt와 같습니다. 이는 /main/foo.txt로 구문 분석됩니다.
  • PHP 네임스페이스의 요소는 동일한 원칙을 사용합니다. 예를 들어 네임스페이스 아래의 클래스 이름은 세 가지 방법으로 참조될 수 있습니다.

    정규화되지 않은 이름 또는
  • 또는 . 현재 네임스페이스가 currentnamespace이면 foo는 currentnamespacefoo로 확인됩니다. foo를 사용하는 코드가 전역적이고 어떤 네임스페이스에도 포함되지 않은 경우 foo는 foo로 확인됩니다.

  • 限定名称,或包含前缀的名称,例如$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 &#39;命名空间为:Foo\Bar\Demo&#39;;
        }
    }
?>

2) index.php

<?php
    namespace Foo\Bar;
    include &#39;Demo.php&#39;;
    const FOO = 2;
    function foo() {
        echo &#39;Foo\Bar 命名空间下的 foo 函数<br>&#39;;
    }
    class foo
    {
        static function demo(){
            echo &#39;命名空间为:Foo\Bar<br>&#39;;
        }
    }
    /* 非限定名称 */
    foo();                  // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
    foo::demo();            // 解析为类 Foo\Bar\foo 的静态方法 staticmethod。
    echo FOO.&#39;<br>&#39;;        // 解析为常量 Foo\Bar\FOO
    /* 限定名称 */
    Demo\foo();             // 解析为函数 Foo\Bar\Demo\foo
    Demo\foo::demo();       // 解析为类 Foo\Bar\Demo\foo,
                            // 以及类的方法 demo
    echo Demo\FOO.&#39;<br>&#39;;   // 解析为常量 Foo\Bar\Demo\FOO
                                     
    /* 完全限定名称 */
    \Foo\Bar\foo();         // 解析为函数 Foo\Bar\foo
    \Foo\Bar\foo::demo();   // 解析为类 Foo\Bar\foo, 以及类的方法 demo
    echo \Foo\Bar\FOO.&#39;<br>&#39;; // 解析为常量 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 = &#39;Another&#39;;
    $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 也是一个完全限定名称。

名称解析遵循下列规则:

  • 함수, 클래스 및 상수의 정규화된 이름에 대한 호출은 컴파일 타임에 해결됩니다. 예를 들어 새 AB는 클래스 AB로 해석됩니다.
  • 모든 정규화되지 않은 이름과 정규화되지 않은 이름(완전히 정규화되지 않은 이름)은 현재 가져오기 규칙에 따라 컴파일 타임에 변환됩니다. 예를 들어 네임스페이스 ABC를 C로 가져오면 CDe()에 대한 호출은 ABCDe()로 변환됩니다.
  • 네임스페이스 내에서 가져오기 규칙에 따라 변환되지 않은 모든 정규화된 이름은 앞에 추가됩니다. 현재 네임스페이스 이름으로 변경합니다. 예를 들어 네임스페이스 AB 내에서 CDe()가 호출되면 CDe()는 ABCDe()로 변환됩니다.
  • 규정되지 않은 클래스 이름은 현재 가져오기 규칙에 따라 컴파일 타임에 변환됩니다(대신 전체 이름이 사용됨). 짧은 수입 이름). 예를 들어 네임스페이스 ABC를 C로 가져오면 new C()는 new ABC()로 변환됩니다.
  • 네임스페이스(예: AB) 내에서 정규화되지 않은 이름에 대한 함수 호출은 런타임에 해결됩니다. 예를 들어 foo() 함수 호출은 다음과 같이 구문 분석됩니다.
    • 현재 네임스페이스에서 ABfoo()라는 함수를 검색합니다.

    • 해 보세요. 전역 공간에서 foo() 함수를 찾고 호출합니다.

  • 네임스페이스(예: AB) 내의 정규화되지 않은 이름 또는 정규화된 이름 클래스(정규화되지 않은 이름)에 대한 호출은 런타임 시 해결됩니다. new C()와 new DE()를 호출하는 구문 분석 과정은 다음과 같습니다.
    • new C() 구문 분석:

      • 현재 ABC 클래스를 찾습니다.
      • ABC 클래스를 자동 로드해 보세요.
    • new DE() 구문 분석:

      • 클래스 이름 앞에 현재 네임스페이스 이름을 추가하여 ABDE로 검색한 후 클래스에 대해 ;
      • ABDE 클래스를 자동 로드해 보세요.
    • 글로벌 네임스페이스에서 글로벌 클래스를 참조하려면 정규화된 이름인 new C()를 사용해야 합니다.

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 네임스페이스란 무엇입니까? PHP의 네임스페이스에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 biancheng.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제