命名空间基本上是为了避免类和函数的命名冲突,主要是与PHP内置类的冲突,以及与第三方获取的代码冲突。
换句话说,我们自己的代码与其他人编写的代码之间存在冲突。
我们可以将命名空间视为类似于文件系统中的目录。
同一个目录中不能存在两个同名的文件一样,同一个命名空间中也不能存在两个同名的类或者函数。
PHP 中的命名空间
默认情况下,我们在“根”类型的命名空间中工作,这意味着如果我们决定将函数命名为 trim(),它将导致脚本中出现致命错误,因为 PHP 已经有一个名为 trim() 的内置函数)。
PHP Fatal error: Cannot redeclare trim() in... PHP 致命错误:无法在...中重新声明 trim()
现在,如果我们选择更改代码的命名空间,请在脚本顶部的某处编写如下内容:
namespace your_root_name_space;
突然之间,我们将神奇地能够用我们自己的“覆盖”PHP 内置的trim() 函数。
只需尝试在终端中运行以下命令:
namespace your_root_name_space; function trim() { echo 'Yaaah'; } trim();
并且不用担心失去调用现有 PHP 函数的能力!只有我们明确声明的函数才会被覆盖。
同样的逻辑适用于类,只有一个微小的区别。
例如,PHP 有一个名为 DateTime 的内置类用于处理时间戳。
通常你会像这样使用这个类:
$date = DateTime::createFromFormat('j-M-Y', '15-Feb-2009'); echo $date->format('Y-m-d');
如果你改变了命名空间,然后尝试调用这个类,你会得到这样的错误:
PHP 致命错误:未捕获的错误:在...中找不到类“your_root_name_space\DateTime” PHP Fatal error: Uncaught Error: Class 'your_root_name_space\DateTime' not found in... Stack trace: #0 {main} thrown in...
这样做的原因是 PHP 现在正在命名空间中寻找该类。
要解决此问题,我们必须在实例化 DateTime 类时添加反斜杠:
namespace your_root_name_space; $date = \DateTime::createFromFormat('j-M-Y', '15-Feb-2009'); echo $date->format('Y-m-d');
输出应如下所示:
2009-02-15
反斜杠字符“\”用作命名空间分隔符,类似地,它可以用作文件系统中的目录分隔符。
所以,实际上我们在 \DateTime 之前包含它是在告诉 PHP 在根中查找类。
PHP 自己的根。
这与文件系统的工作方式没有什么不同。
我们可能还想阅读绝对路径和相对路径
命名空间和目录
将命名空间映射到目录结构通常是一种很好的做法,但这不是必需的。
这意味着,如果类中的命名空间是: your_root_name_space\lib\some_class\ 类文件的文件系统位置应该是: your_root_name_space/lib/some_class/some_class.php
根据 PSR 编码标准,PHP 类名也应该与文件名匹配。
这可以使用 PSR 自动加载器自动加载文件。