🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 命名空间 命名空间简单的说就是类似文件的路径。为了解决命名冲突的问题产生的。比如在我们的代码中经常遇到以下问题。 自己在一个目录写了一个类叫A. 另外一个人也写了一个类叫A。就会产生一个冲突。最初的框架,比如ci框架,都是类的名字前面加上一CI_的前缀防止命名冲突。 命令空间的思想来源于路径。比如在一个/www/目录下不能存在两个相同的文件。但是可以文件放在/www/a/ 、/www/b下面,这样两个文件就不会冲突。同理命名空间。如果在\www\a\A、\www\b\A 这两个类也可以可以同时存在的。 命名空间的定义使用**namespace** 定义。只有类(包括抽象类和traits)、接口、函数和常量受到命名空间的影响。 命名空间的定义必须在脚本的首行。不能有bom,否则会出错。 定义子命名空间用\分割。 也可以在一个文件定义多个命名空间。但是一般不这么做。 ```php namespace app; #子命名空间 namespace app\model; namespace app { function test(){} } namespace app2{ function test(){} } namespace { app\test(); app2\test(); } ``` ### 命名空间基础 命名空间和路径原理相似。所以有相对、绝对 - 非限定名称、不包含前缀的类名称。类似a.php 比如include('a.php') ```php $a = new Test();// 如果这个文件定义的命名空间是app。那么就是访问的 app\Test类。 ``` - 限定名称,或包含前缀 类似 文件路径中的 a/c.php这种形式 ```php $a = new model\Test(); //如果该文件的命名空间是app。则访问的就是app\model\Test ``` - 完全限制 类似文件中的绝对路径 /www/a.php ```php $a = new \app\Test(); ``` ### 别名和导入 命名空间支持别名和引入外部的名字 所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名 ```php namespace a; use app\model; use app\test\model as model2; ``` ### 全局命名空间 如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 *\\* 表示该名称是全局空间中的名称 ```php namespace app; function test(){ new \Redis(); } ``` ### 名词解析 ```php namespace 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" ```