“命名空间”将是我们学习PHP最后一个知识点。做个示例引出概念:
假如在我们的拓展库Lib有一个类,就叫“Test”:
随意在另外一个文件夹里也有一个“Test”类,比如在Model里。
在我们的项目中出现了同名的类,为了让在“Model”目录里的Test类也被加载进来,把10-12行改成15-17行。
当实例化这个类时会发生什么情况,请看:
报了一个致命错误,类重名了!
在PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决。
可实际开发中,会有很多模块,在命名中经常会出现不同模块同名的现象。类名会给人很直观的作用,告诉这个类是做什么的,如果只是为了避免与其他模块的类同名就随意起个其他名字,这样写程序是不好的。
所以我们写程序时要保持一个好习惯,就是加前缀。mysql设计表时最好给每个表名加一个前缀,类也应该加一个前缀。就像这个“Test类”,在Lib里的起名“LTest类”,在Model里的起名“MTest类”。
我们这节要学习的“命名空间”起的就是这样一个作用,为类以另外一种方式加“前缀”。
示例:
Lib中的Test类给它定义一个命名空间“lib”,语法: namespace 名字;
注意:定义命名空间之前不能有任何代码。
运行1.php看结果:
不报错了,而且Model中的Test类也被实例化了。可以说加前缀成功了,两个同名的类以区分开。如果想实例化Lib中的Test类,那该怎么做?看代码:
看23行代码,如果要实例化Lib中的test,在实例化之前要加上test类的命名空间“\lib\”。在魔术函数里为了正确获取类名,9、10代码是新加的代码。
看过这样一个例子,是不是对命名空间这个功能有了一定的认识。
大家可以这样去理解:没有命名空间的类,我们就想象着是在“\”目录里(第24行代码可以这样写new \Test);为Test类加了命名空间“lib”,我们就想象着是把Test类放入了“\lib\”目录里了。这样思考问题,命名空间就非常好理解了。
命名空间名字中可以带“\”,比如:
为Model中的Test.php起个命名空间“mo\de\l”。
如果实例化类时把最左边的“\”去掉,会发生什么情况?
1.php中25行不会出错。
Model中Test类中16行去掉就会出错:
直接从错误中很直观就能看出错在哪了。
use的用法
直接看示例,作用一目了然:
25、26行代码作用等于22行。
经测试可正常显示。
use语法:use 命名空间名\类名; 切记不要忘记了类名!
关于use的理解:命名空间是“lib”的Test类,我们想象着是把Test类放入了“\lib\”目录里了。而使用use的作用,我们可理解为又把“lib”的Test类复制了一份放入了当前目录里(就是当前的命名空间里)。所以在使用use之前,要确保当前目录(当前命名空间)里没有Test类,不然又会报重名的错误。
如何解决重名的错误呢?
使用as语法,起别名,示例:
namespace animal\dog; class Life{ function __construct(){ echo 'dog life!'; } } namespace animal\cat; class Life{ function __construct(){ echo 'cat life!'; } } use animal\dog\Life as dog; new dog();
使用use以后,如何获取类的完全限定名称?
完全限定名称就是包含完整命名空间的类名,就像上面举例的 lib\Test mo\de\l\Test。
自 PHP 5.5 起,关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。
可把“class”理解为类的一个默认常量。《类常量》
总结:
命名空间还是会经常用到的,它主要起到加“前缀”的作用,对其他没什么影响。命名空间也没什么深奥的地方,只要有心去研究下很快就能明白。
写项目时,尤其是复杂的大项目,一开始就应该做好命名规范。