namespace的引入是为了解决项目中的重名问题(类、方法、变量等),默认所有的访问都是在当前命名空间下的(如不设置命名空间,则是在全局命名空间下),当产生冲突的时候,就会发生错误,比如File_A中有个test()函数,File_B中也有个test()函数,当把File_A和File_B引入到同一个File_C中的时候,访问test()方法就会出现编译错误,因为不知道要去访问那个test()函数,就像4个人都叫李四,并不知道那个是你找的李四。而给文件设置命名空间之后,我们就可以通过在限定的命名空间下找test()函数,就像找家主A的李四,或者家住B的李四,这样就解决了命名冲突问题。1
2
3
4namespace np_01;
function testMethod() {
echo 'np_01<hr>';
}
1 | namespace np_02; |
1 | /* |
- 完全限定名称的类、方法、常量访问,只单纯按照命名空间解析,不拼接当前命名空间
- 在命名空间内部,访问非限定名称和非完全限定名称的类、方法、常量,会在前面拼接当前命名空间,然后按照规则3、4进行访问,且如果拼接之后的完整命名空间是
new A\B\C\D()
,那么它是等价于new \A\B\C\D()
的 - 在命名空间内部(比如A\B)访问一个非限定名称的方法、常量,那么会先在当前命名空间访问,然后是全局命名空间,比如直接通过var_dump(‘aa’)访问系统函数(如果是非完全限定的,则不会去全局命名空间找,访问不到依然报错,比如\NP\np_02\var_dump())
- 在命名空间内部(比如A\B)访问一个非限定和非完全限定的类,只会在拼接之后的命名空间中查找,比如new C,是A\B\C,new C\D,则是A\B\C\D,不会在全局命名空间下找,因此在命名空间中访问全局类如new \mysqli(‘localhost’, ‘zzzz’)必须使用完全限定名称\className(),防止拼接当前命名空间。
一点小细节:定义命名空间的前面,别写其他代码。
命名空间可以像文件路径一样细化为多层子命名空间,把1.php的命名空间修改为NP\np_01
,把2.php的命名空间修改为NP\np_02
,把3.php并设置其命名空间为NP
。
使用use关键字引入命名空间,访问命名空间下的不同内容,修饰关键字也不同,类是use 命名空间\类型,函数是use function 命名空间\函数名,常量是use const 命名空间\常量名 AS关键字设置别名。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//1. 不使用use关键字
/*
require_once '1.php';
\NP\np_01\testMethod();
*/
// 2.使用use关键字
/*
namespace NP\np_04;
use function NP\np_01\testMethod; // 不使用AS别名,则以最后部分为别名
require_once '1.php';
testMethod();
*/
// 3.use + AS 别名
/*
namespace NP\np_04;
use function NP\np_01\testMethod AS zwk;
require_once '1.php';
zwk();
*/