PHP命名空间
命名空间
定义
PHP5.3.0 新增的一种封装事物的方法,解决编写的类库或应用程序时命名冲突的问题,类似window系统的文件夹
关键字 namespace
- 必须声明命名空间,必须处于程序脚本的第一条语句,即声明前不能有任意的字符输出,如空格或html标签等;
- 命名空间中可以包含任意合法的php代码,受命名空间影响的有类、函数、常量
- PHP >=5.3.0 开始支持
- namespace 可以代表当前空间,类似类中的self;
namespace\Home\Student()
创建一个namespace.php文件
1 |
|
使用命名空间
- 使用时需要指定空间名称
- 命名空间与类、函数、局部常量间使用
\
分割; - 普通代码 变量、常量不在命名空间中
在当前目录创建一个index.php,引入上面的创建的namespace.php文件,进行测试使用
1 |
|
命名空间子空间
- 使用
\
斜线分割子空间。如 Home\Controller\Student();
定义
1 |
|
使用
1 |
|
命名空间路径
- 文件系统中访问文件的方式
- 相对文件名形式:如:a.txt ,会在当前执行文件的所在文件夹中查找a.txt;
- 相对路径名形式:如:sub/a.txt ,会在当前执行文件的所在文件夹中查找sub文件夹,再在sub中查找a.txt;
- 绝对路径名形式:如:/main/a.txt ,会从根目录(window系统中,会从执行文件的所在盘符中)开始查找main文件夹,再在main中查走a.txt;
- 访问命名空间中的元素方式
- 非限定名称(不带任何前缀)。$obj = new User(),会在单前空间中查找
- 限定名称(带相对空间的前缀)。$obj = new Home\User(),会在当前空间找子空间Home中的User类
- 完成限定名称(从根空间开始)。$obj = new \Home\User(),会从根空间开始查找Home中的User类
命名空间use
使用
- 使用
use
关键字use App\Student;
- 如果引入类与当前空间的类起冲突时,可以使用
as
起别名;如use App\Student as Stu;
- 使用
use
引入后,可以直接使用类名称;$student = new Student()
命名空间和动态语言特征
PHP 命名空间的实现受到其语言自身的动态特征的影响。因此,如果要将下面的代码转换到命名空间中,动态访问元素。
1 |
|
必须使用完全限定名称(包括命名空间前缀的类名称)。注意因为在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的
命名空间的顺序
自从有了命名空间之后,最容易出错的该是使用类的时候,这个类的寻找路径是什么样的了。
1 |
|
名称解析遵循下列规则:
对完全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。
所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 *A\B\C\D\e()*。
在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e()*,则 *C\D\e() 会被转换为 A\B\C\D\e() 。
非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。
在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数foo()的调用是这样解析的:
- 在当前命名空间中查找名为 A\B\foo() 的函数
- 尝试查找并调用 全局(global) 空间中的函数 *foo()*。