Php 简明教程
PHP - Namespaces
我们经常将文件组织在不同的文件夹中。通常情况下,一个文件夹包含与某个目标、应用程序或类别相关联的文件。一个文件夹不能包含两个具有相同名称的文件,尽管不同的文件夹可能具有一个名称相同的文件,因此每个文件路径都是不同的。
PHP 中的命名空间理念有点类似。在 PHP 中,命名空间允许在不同上下文中使用相同名称的类或函数或常量,而不会出现任何冲突,从而封装这些项。
PHP 命名空间是根据它们的关联性对类/函数等进行的逻辑分组。正如同名的文件可以存在于两个不同的文件夹中一样,命名空间中也可以定义一个特定名称的类。此外,由于我们指定文件的完整路径来获取访问权限,因此我们需要指定类及其命名空间的完整名称。
随着应用程序规模的不断增大,包括许多类和函数定义,为每个类/函数提供一个唯一的名称可能会变得繁琐并且不够优雅。使用命名空间可让您以一种简洁的方式组织此类代码块。例如,如果我们需要声明一个 calculate() 函数来计算面积和税费,我们可以创建两个命名空间 area 和 tax,并在其中使用 calculate() 而不必将它们定义为类似 calculate_area() 和 calculate_tax() 的内容。
Advantages of Namespace
下面列出了一些使用 PHP 中的命名空间的优点 −
-
命名空间有助于避免某人使用第三方类/函数/常量定义的类/函数/常量之间的名称冲突。
-
命名空间提供了对 Extra_Long_Names 进行别名(或缩短)的能力,从而提高了源代码的可读性。
-
PHP 命名空间提供了一种对相关的类、接口、函数和常量进行分组的方法。命名空间名称不区分大小写。
Defining a Namespace
PHP 的名称空间关键字用于定义新的命名空间。
namespace myspace;
包含命名空间的 “.php” 文件必须在文件顶部声明命名空间,然后再声明任何其他内容(声明指令除外)。在命名空间中声明类、函数和常量会影响其访问权限。
一个 PHP 脚本可以除了定义命名空间之外,还包含其他代码。为了加载在相同代码中定义的命名空间,PHP 具有“use”关键字。
use myspace;
Include Namespace
可以有一个脚本包含名称空间声明,以及在其中使用 include 语句加载该名称空间的另一个脚本。
b.php
<?php
include 'a.php';
myspace\hello();
?>
它将生成以下 output −
Hello World in myspace
在当前的脚本(如上所述的“b.php”)中,可能还有一个函数与 include 文件中函数名称相同。附加名称空间的完全限定函数,帮助解析器解决名称冲突。
Example
请看以下示例:
<?php
include 'a.php';
function hello() {
echo "Hello World from current namespace";
}
hello();
myspace\hello();
?>
它将生成以下 output −
Hello World from current namespace
Hello World in myspace
Example
如上所述,名称空间声明必须在最上面,紧跟在 <?php 标签的后面。否则,解析器会抛出致命错误。
<?php
echo "hello"
namespace myspace;
function hello() {
echo "Hello World";
}
use myspace;
myspace\hello();
?>
它将生成以下 output −
PHP Parse error: syntax error, unexpected token "namespace",
expecting "," or ";" in /home/cg/root/67771/main.php on line 4
上面的错误信息明确指出,在名称空间声明之前,只允许出现“declare 语句”。
<?php
declare (strict_types=1);
namespace myspace;
function hello() {
echo "Hello World";
}
use myspace;
myspace\hello();
?>
Relative Namespace
可以通过相对于名称空间的路径引用当前名称空间中的对象,如函数、类和常量。
在下面的示例中,“b.php”包含一个带有 hello() 函数和 TEMP 常量的名称空间 space1\myspace。这些对象也在“a.php”中定义的名称空间 space1 中被定义。
显然,当“b.php”被包含在“a.php”时,“myspace”是“space1”的子空间。因此,通过对其相对名称空间(也是 TEMP 常量)加上前缀来调用来自“myspace”的 hello()。
b.php
<?php
namespace space1\myspace;
const TEMP = 10;
function hello() {
echo "Hello from current namespace:" . __NAMESPACE__ . ;
}
?>
a.php
<?php
namespace space1;
include 'b.php';
function hello() {
echo "Hello from current namespace:" . __NAMESPACE__ . ;
}
const TEMP = 100;
hello(); // current namespace
myspace\hello(); // sub namespace
echo "TEMP : " . TEMP . " in " . __NAMESPACE__ . ;
echo "TEMP : " . myspace\TEMP . " \\in space1\\myspace\n";
?>
它将生成以下 output −
Hello from current namespace:space1
Hello from current namespace:space1\myspace
TEMP : 100 in space1
TEMP : 10 in space1\myspace
Absolute Namespace
也可以通过附加绝对名称空间路径来访问任何名称空间中的函数/常量。例如,“b.php”中的 hello() 是“\space\myspace\hello()”。
a.php
<?php
namespace space1;
include 'b.php';
function hello() {
echo "Hello from current namespace:" . __NAMESPACE__ . ;
}
const TEMP = 100;
\space1\hello(); //current namespace
\space1\myspace\hello(); //sub namespace
echo "TEMP: " . \space1\TEMP . " in " . __NAMESPACE__ . ;
echo "TEMP: " . \space1\myspace\TEMP . " in space1\\myspace\n";
?>
NAMESPACE 是 PHP 中的预定义常量,用于返回当前名称空间的名称。
Namespace Rules
通过遵循以下规则,可以解决不同名称空间之间出现的函数/类/常量名称冲突:
-
不带名称空间分隔符符号(/)的名称空间标识符表示其正在引用当前名称空间。这是一个不合格的名称。
-
如果它包含分隔符符号,如 myspace\space1,则解析为 myspace 下的子名称空间 space1。这种类型命名是相对名称空间。
-
完全限定名称空间的名称以“\”字符开头。例如,“\myspace”或“\myspace\space1”。
-
完全限定名称解析为绝对名称空间。例如,\myspace\space1 解析为 myspace\space1 名称空间。
-
如果名称出现在全局名称空间中,“namespace\”前缀会被移除。例如,“namespace\space1”解析为 space1。
-
然而,如果它出现在另一个名称空间内,则其处理方式有所不同。例如,如果 namespace\space1 在 myspace 中,则它等同于“myspace\space1”。
-
限定名称中的名称的第一段根据当前类/名称空间导入表进行翻译。
-
如果没有导入规则适用,则在名称前加上当前名称空间。
-
类名类型名称根据类/名称空间导入表进行翻译,函数名称根据函数导入表进行翻译,常量根据常量导入表进行翻译。
-
对于不合格名称,如果未应用导入规则并且名称指向函数或常量,且代码在全局命名空间之外,则该名称在运行时解析。首先,它从当前名称空间查找函数,然后尝试查找并调用全局函数。