简介
从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。
简单来说,解决类,函数的重名问题,相当于电脑的文件夹。
例如:另外,在目录 /a/b
外访问 aa.php
文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /a/b/aa.php
,这个原理应用到程序设计领域就是命名空间的概念。
图例:
文件 aa.php
可以同时在目录 a/b
和 a/c
中存在,
但在同一个目录中不能存在两个 aa.php
文件。
解决了什么问题
命名空间可以用来解决在编写「类库」或「应用程序」时创建可重用的代码如类或函数时碰到的两类问题:
- 用户编写的代码与PHP内部的 类/函数/常量 或 第三方类/函数/常量 之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
注意
在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。另外,所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前
命名空间的分隔符是反斜杠 \ , 不是 /
多数框架中,命名空间路与文件夹路径需要一致
命名空间一般与实际文件夹对应
- 实际开发中不建议一个文件内写多个命名空间
语法
定义命名空间
命名空间通过关键字「namespace」来声明。
如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间,除了一个 declare 关键字以外。
namespace mya;
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
var_dump(new a()); //输出:object(mya\a)#1 (0) { }
输出:命名空间为 mya
定义子命名空间
namespace mya\myb;
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
var_dump(new a()); //输出:object(mya\myb\a)#1 (0) { }
输出:命名空间为 mya/myb
在同一个文件夹下定义多个命名空间
注意:在实际的编程实践中,非常不提倡在同一个文件中定义多个命名空间。这种方式的主要用于将多个 PHP 脚本合并在同一个文件中。
有两种定义的语法
第一种(不推荐):定义多个命名空间,简单组合语法
不建议使用这种语法,建议使用下面那种语法
namespace mya;
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
var_dump( new a() ); //输出:object(mya\a)#1 (0) { }
namespace myb;
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
var_dump( new a()); //输出:object(myb\a)#1 (0) { }
第二种(推荐):定义多个命名空间,大括号语法
namespace mya{
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
}
var_dump( new a() ); //输出:object(mya\a)#1 (0) { }
namespace myb{
class a{
function aa(){
return '我在命名空间 mya 下';
}
}
}
var_dump( new a()); //输出:object(myb\a)#1 (0) { }
使用命名空间
在使用命名空间之前,必须了解 PHP 是如何知道要使用哪一个命名空间中的元素的。
相对路径:直接输入子命名空间,以当前代码所在命名空间计算
绝对路径:以 \ 开头的完整路径, use 无须 / ,默认就是绝对路径
可以将 PHP 命名空间与文件系统作一个简单的类比。在文件系统中访问一个文件有三种方式:
相对文件名形式如 foo.txt 。它会被解析为 currentdirectory/foo.txt,其中 currentdirectory 表示当前目录。因此如果当前目录是 /home/foo,则该文件名被解析为 /home/foo/foo.txt 。
相对路径名形式如 subdirectory/foo.txt 。它会被解析为 currentdirectory/subdirectory/foo.txt 。
绝对路径名形式如 /main/foo.txt 。它会被解析为 /main/foo.txt 。
namespace mya\a;
class a{
function aa(){
return '我在命名空间 mya\a 下';
}
}
namespace mya\b;
class a{
function aa(){
return '我在命名空间 mya\b 下';
}
}
//非限定名称
var_dump( new a() ) ;
//完全限定名称
var_dump( new \mya\a\a() );
输出:
导入/别名 (use / as)
use = 载入指定命名空间 , use 无须 / ,默认就是绝对路径
as = 别名,起一个别名,方便调用
namespace my\a\k{
class a{
function aa(){
return '我在命名空间 mya\a 下';
}
}
var_dump( new a() ) ;
}
//导入
namespace my\b\kk{
//导入
use my\a\k\a;
class b{
function bb(){
return '我在命名空间 mya\b 下';
}
}
var_dump( new a() ) ;
}
//导入并重命名
namespace my\b\kk{
//导入并重命名
use my\a\k\a as ww;
class b{
function bb(){
return '我在命名空间 mya\b 下';
}
}
var_dump( new ww() ) ;
}