使用namespace
关键字可以定义命名空间,定义命名空间后,其中的代码就被一个单独的空间给隔离了。
一个文件中可以有多个命名空间,其中第一个命名空间的定义语句前不能有任何代码(php标签除外)。
<?php
namespace A; #
class 字母{ # 此区域就是命名空间A的区域
public $字母 = 'A'; #
} #
namespace B; #
class 字母{ # 此区域与之后的全部区域都是命名空间B的区域
public $字母 = 'B'; #
} #
# 此例中的类可以理解为正常的类,为了节约篇幅,这里仅有一个属性。
以上代码中,命名空间A
中有一个字母
类,命令空间B
中也有一个字母
类。如果在文件下方实例化字母类
,是实例化的哪个字母类
呢?
<?php
namespace A;
class 字母{
public $字母 = 'A';
}
namespace B; #
class 字母{ #
public $字母 = 'B'; #
} # 此区域都是命名空间B的区域
#
$obj = new 字母(); #
printf($obj->字母); # 结果为:B #
那么我想要实例化命名空间A
中的字母类
,如何做呢?
<?php
namespace A;
class 字母{
public $字母 = 'A';
}
namespace B;
class 字母{
public $字母 = 'B';
}
$obj = new \A\字母(); # 与上例对比,只有这里修改了
printf($obj->字母); # 结果为:A
在上例中,\A\字母()
是关键要素。
其实,命名空间的层级结构与linux
的目录文件层级结构很相似。
第一个\
是命名空间的根命名空间
,我们定义的命名空间都是在根命名空间下定义的,一般都是省略掉,如果不省略的话,那么命名空间A需要这样定义:namespace \A
。
然后 A
就是代码中定义的命令空间。
第二个\
可以理解为目录的层级结构,除了第一个\
,之后的\
都表示层级结构。
在最后一个 \
之后,就是要使用的类(本例中是类,也可以是自定义函数等)。如:
<?php
namespace A;
function 字母(){
return 'A';
}
namespace B;
printf(\A\字母()); # 结果为:A
如果我们将开头的例子当作单独的一个文件,起名为字母.php
,我们再在另一个文件(使用.php
)中导入并使用:
<?php
include '字母.php';
$字母A = new \A\字母();
printf($字母A->字母()); # 结果为:A
$字母B = new \B\字母();
printf($字母B->字母()); # 结果为:B
我们会发现每次调用命名空间下的类、方法都要加上命名空间,如果使用频繁呢?如果命名空间层级很多呢?如果导入的文件将命名空间修改了,我们是不是需要一行代码一行代码去找这些使用的命名空间?
use 关键字可以将需要用到的命名空间下的类、方法提前导入。这样在实际使用中就无需写命名空间了。就是命名空间修改了,也仅需要修改 use 关键字导入的那一行即可。
<?php
include '字母.php';
use A\字母 as A字母; # as 表示别名,这里就表示给 字母 起个别名:A字母
use B\字母;
$obj = new A字母(); # 使用别名
printf($obj->字母); # 结果为:A
$obj = new 字母(); # 没有设置别名,直接使用类名
printf($obj->字母); # 结果为:A