> 백엔드 개발 > PHP 튜토리얼 > PHP 네임스페이스에 대한 완전한 숙달

PHP 네임스페이스에 대한 완전한 숙달

小云云
풀어 주다: 2023-03-20 20:20:01
원래의
1583명이 탐색했습니다.

네임스페이스는 사용자가 작성한 코드와 PHP 내부 클래스/함수/상수 또는 타사 클래스/함수/상수 간의 이름 충돌을 해결하는 데 사용됩니다. 소스 코드 가독성을 높이기 위해 매우 긴 식별자 이름에 대한 별칭(또는 짧은) 이름을 만듭니다.

모든 합법적인 PHP 코드가 네임스페이스에 포함될 수 있지만 클래스(추상 클래스 및 특성 포함), 인터페이스, 함수 및 상수와 같은 유형의 코드만 네임스페이스의 영향을 받습니다.

파일에 네임스페이스가 포함된 경우 소스 파일이 인코딩되는 방법을 정의하는 데 사용되는 declare 키워드인 declare 문을 제외한 다른 모든 코드보다 먼저 네임스페이스를 선언해야 합니다. 공백을 포함한 코드는 네임스페이스 선언 앞에 나타날 수 없습니다.

다른 PHP 언어 기능과 달리 동일한 네임스페이스를 여러 파일에 정의할 수 있으므로 동일한 네임스페이스의 내용을 나누어 다른 파일에 저장할 수 있습니다.

하위 네임스페이스 정의

<?phpnamespace MyProject\Sub\Level;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() {/* ... */ }
로그인 후 복사

동일한 파일에 여러 네임스페이스 정의

<?phpnamespace MyProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }namespace AnotherProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
로그인 후 복사

이 구문을 사용하여 단일 파일에 여러 네임스페이스를 정의하는 것은 권장되지 않습니다. 다음 중괄호 형식의 구문을 사용하는 것이 좋습니다.

<?phpnamespace MyProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}namespace AnotherProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}
로그인 후 복사

실제 프로그래밍 실습에서는 동일한 파일에 여러 네임스페이스를 정의하는 것을 매우 권장하지 않습니다. 이 방법은 주로 동일한 파일에 여러 PHP 스크립트를 결합하는 데 사용됩니다.

전역 비네임스페이스의 코드와 네임스페이스의 코드를 결합하려면 중괄호 형태의 구문만 사용할 수 있습니다. 전역 코드는 이름이 없는 네임스페이스 문과 함께 중괄호로 묶어야 합니다.

클래스는 세 가지 방법으로 참조할 수 있습니다.

  1. 정규화되지 않은 이름 또는 $와 같은 접두사를 포함하지 않는 클래스 이름 a =new foo(); 또는 foo::staticmethod();. 현재 네임스페이스가 currentnamespace인 경우 foo는 currentnamespacefoo로 확인됩니다. foo를 사용하는 코드가 전역 코드이고 어떤 네임스페이스에도 코드를 포함하지 않는 경우 foo는 foo로 확인됩니다. 경고: 네임스페이스의 함수 또는 상수가 정의되지 않은 경우 정규화되지 않은 함수 또는 상수 이름은 전역 함수 또는 상수 이름으로 확인됩니다.

  2. 정식 이름 또는 접두사가 포함된 이름(예: $a = new subnamespacefoo(); 또는 subnamespacefoo::staticmethod();). 현재 네임스페이스가 currentnamespace이면 foo는 currentnamespacesubnamespacefoo로 확인됩니다. foo를 사용하는 코드가 전역 코드이고 어떤 네임스페이스에도 포함되지 않은 코드인 경우 foo는 subnamespacefoo로 해석됩니다.

  3. 정규화된 이름 또는 전역 접두사 연산자가 포함된 이름(예: $a = new currentnamespacefoo(); 또는 currentnamespacefoo::staticmethod();). 이 경우 foo는 항상 currentnamespacefoo 코드의 리터럴 이름으로 확인됩니다.

전역 클래스, 함수 또는 상수에 액세스하려면 strlen(), Exception 또는 INI_ALL과 같은 정규화된 이름을 사용할 수 있습니다.

참고: 상위 파일에 포함된 하위 파일에 포함된 파일의 상대 경로는 하위 파일 디렉터리가 아닌 상위 파일 디렉터리에 대한 것입니다.

PHP는 현재 네임스페이스 내의 요소에 액세스하는 두 가지 추상 방법인 __NAMESPACE__ 매직 상수와 __NAMESPACE__魔术常量和namespace关键字。

__NAMESPACE__namespace

키워드를 지원합니다.

__NAMESPACE__는 문자열을 표현할 수 있으며, 그 외는 네임스페이스와 동일합니다.

use 연산자를 사용하여 별칭 가져오기/사용

<?phpnamespace foo;use My\Full\Classname as Another;// 下面的例子与 use My\Full\NSname as NSname 相同use My\Full\NSname;// 导入一个全局类use ArrayObject;// importing a function (PHP 5.6+)use function My\Full\functionName;// aliasing a function (PHP 5.6+)use function My\Full\functionName as func;// importing a constant (PHP 5.6+)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(); // calls function My\Full\functionNameecho CONSTANT; // echoes the value of My\Full
로그인 후 복사

use 연산자를 통해 별칭 가져오기/사용, 여러 use 문이 한 줄에 포함됨

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化 My\Full\Classname 对象NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
로그인 후 복사

가져오기 및 동적 이름

가져오기 작업 실행 파일을 컴파일하고 있지만 동적 클래스 이름, 함수 이름 또는 상수 이름은 그렇지 않습니다.

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化一个 My\Full\Classname 对象$a = &#39;Another&#39;;$obj = new $a;      // 实际化一个 Another 对象
로그인 후 복사

가져오기 및 정규화된 이름

가져오기 작업은 정규화되지 않은 이름과 정규화된 이름에만 영향을 미칩니다. 정규화된 이름은 결정적이므로 가져오기의 영향을 받지 않습니다.

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // instantiates object of class My\Full\Classname$obj = new \Another; // instantiates object of class Another$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing$obj = new \Another\thing; // instantiates object of class Another\thing
로그인 후 복사

전역 공간 설명 사용

<?phpnamespace A\B\C;/* 这个函数是 A\B\C\fopen */function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
}
로그인 후 복사

PHP는 네임스페이스 내에서 정규화되지 않은 클래스, 함수 또는 상수 이름을 발견하면 다른 우선 순위 전략을 사용하여 이름을 확인합니다. 클래스 이름은 항상 현재 네임스페이스의 이름으로 확인됩니다. 따라서 시스템 내부에 있거나 네임스페이스에 포함되지 않은 클래스 이름에 액세스할 때는 정규화된 이름을 사용해야 합니다. 함수와 상수의 경우, 함수나 상수가 현재 네임스페이스에 없으면 PHP는 전역 공간의 함수나 상수를 사용하게 됩니다.
    <?phpnamespace A\B\C;class Exception extends \Exception {}$a = new Exception(&#39;hi&#39;); // $a 是类 A\B\C\Exception 的一个对象$b = new \Exception(&#39;hi&#39;); // $b 是类 Exception 的一个对象$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
    로그인 후 복사
    <?phpnamespace A\B\C;const E_ERROR = 45;function strlen($str){
        return \strlen($str) - 1;
    }echo E_ERROR, "\n"; // 输出 "45"echo INI_ALL, "\n"; // 输出 "7" - 使用全局常量 INI_ALLecho strlen(&#39;hi&#39;), "\n"; // 输出 "1"if (is_array(&#39;hi&#39;)) { // 输出 "is not array"
        echo "is array\n";
    } else {    echo "is not array\n";
    }
    로그인 후 복사
  1. 이름 확인은 다음 규칙을 따릅니다.

  2. 완전한 이름을 가진 함수, 클래스 및 상수에 대한 호출은 컴파일 타임에 확인됩니다. 예를 들어 새 AB는 클래스 AB로 확인됩니다.

    🎜🎜모든 정규화되지 않은 이름과 정규화된 이름(정규화되지 않은 이름)은 현재 가져오기 규칙에 따라 컴파일 타임에 변환됩니다. 예를 들어 네임스페이스 ABC를 C로 가져온 경우 CDe()에 대한 호출은 ABCDe()로 변환됩니다. 🎜
  3. 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。

  4. 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。

  5. 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的:

    1. 在当前命名空间中查找名为 A\B\foo() 的函数

    2. 尝试查找并调用 全局(global) 空间中的函数 foo()。

  6. 在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析:

    new D\E()的解析:

    为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()。

    1. 在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。

    2. 尝试自动装载类 A\B\D\E。

    3. 在当前命名空间中查找A\B\C类。

    4. 尝试自动装载类A\B\C。

<?phpnamespace A;use B\D, C\E as F;// 函数调用foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"\foo();     // 调用全局空间函数 "foo" my\foo();   // 调用定义在命名空间"A\my"中函数 "foo" F();        // 首先尝试调用定义在命名空间"A"中的函数 "F" 
            // 再尝试调用全局函数 "F"// 类引用new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到,则尝试自动装载类 "A\B"new D();    // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到,则尝试自动装载类 "B\D"new F();    // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到,则尝试自动装载类 "C\E"new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现,则尝试自动装载类 "B"new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现,则尝试自动装载类 "D"new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现,则尝试自动装载类 "F"// 调用另一个命名空间中的静态方法或命名空间函数B\foo();    // 调用命名空间 "A\B" 中函数 "foo"B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"D::foo();   // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"\B\foo();   // 调用命名空间 "B" 中的函数 "foo" \B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到,则尝试自动装载类 "B"// 当前命名空间中的静态方法或函数A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"\A\B::foo();  // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"?>
로그인 후 복사

相关推荐:

PHP命名空间详细使用方法

PHP命名空间、性状与生成器详解

实例详解PHP命名空间用法

위 내용은 PHP 네임스페이스에 대한 완전한 숙달의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿