欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于PHP命名空间的讨论

程序员文章站 2022-05-04 12:21:56
什么是命名空间? 根据php.net官方翻译文档描述,命名空间是这样定义的: 什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。 在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题: (1)、用户编写的代码与PHP内部的类/函数/常量或第三方类/函 ......

什么是命名空间?

    根据php.net官方翻译文档描述,命名空间是这样定义的:

什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。

在php中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

(1)、用户编写的代码与php内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。

(2)为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

    这个描述太官方,不太好懂。

    简单地说,这个命名空间,就是用来解决定义的常量、函数和类,存在重名的问题,一是解决用户定义的类/函数/常量与php内部的类/函数/常量同名的问题,二是解决不同软件开发小组或不同软件公司定义的类/函数/常量同名的问题,而你需要同时使用这两个公司定义的类库。

    比如,新冠肺炎防控期间,ahcme学校开发了用于收集学生疫情报告的信息的软件平台,anhui省也开发了省级疫情监测平台,用于汇总各高校疫情信息进行大数据分析和预警。现在,由wisedu公司来做这个对接开发,用于将ahcme学校的填报明细数据每天定时上传到省级疫情平台。

    在wisedu公司开始做对接工作之前,ahcme学校和anhui省都已经基本完成了代码开发,他们有了下面的php代码文件:

achme学校的代码是 ahcme_sample.php文件:

 关于PHP命名空间的讨论

anhui省的代码是 anhui_sample.php文件:

 关于PHP命名空间的讨论

    这两个单位的代码都定义了同样名字的常量、函数和类,但具体的实现细节是不一样的。现在wisedu公司要做的事情就是要将ahcme的学生信息转换成anhui省监控平台所需要的数据格式,以便进行数据上报。

wisedu公司写了下面的测试代码(test.php):

 关于PHP命名空间的讨论

    这样带来一个问题,调用hello函数和实例化student对象,我不知道是使用的是ahcme学校的代码,还是anhui省的代码。更严重的是,运行会报错:

 关于PHP命名空间的讨论

    这是一个严重错误(fatal error),提示是不能重复定义hello函数。当然也会遇到类student不能重复定义。

    怎么解决这个问题呢?那就是给ahcme学校和anhui省的代码,定义在不同的命名空间里面。

如何定义命名空间?

    使用namespace关键字定义命名空间。

    namespace语句必须是php文件中<?php标记下的第1个语句(declare语句除外)。

    *命名空间是\,接下来是一级命名空间,二级命名空间,他们之间用\分隔。

    如\ncov2019\ahcme就是一个二级命名空间,是ncov2019命名空间的子命名空间。

achme学校的代码是 ahcme_sample.php文件:

 关于PHP命名空间的讨论

anhui省的代码是 anhui_sample.php文件:

 关于PHP命名空间的讨论

    这里使用的是二级子命名空间,可以认为这两个单位的项目都是新冠肺炎防控(ncov2019)这个项目的子项目。当然你也可以使用一级命名空间(如anhui和ahcme),这由这几个开发小组共同协商好就行。

    不建议在一个php文件中定义多个命名空间。

    这个时候,wisedu公司的测试代码就可以这样写:

 关于PHP命名空间的讨论

    这里,test.php没有定义命名空间,那他是*命名空间\。那么当前命名空间就是\。

    这样,就能很清楚的知道,$s1对象是ahcme学校的学生,$s2对象是anhui省的大学生了。运行结果也是这样:

 关于PHP命名空间的讨论

当然,作为wisedu公司的代码,他也可以定义命名空间:

 关于PHP命名空间的讨论

    这时,当前命名空间就是ncov2019\wisedu了。不能再像这样去定义ahcme的student对象了:

$s1 = new ncov2019\ahcme\student("11001", "张三");

    因为上面是相对路径的定法。以前当前命名空间是\,转换成绝对路径是\ncov2019\ahcme\student对象,是正确的。现在当前命名空间是ncov2019\wisedu,转换成绝对路径就是\ncov2019\wisedu\ncov2019\ahcme\student对象,当然就不正确了,所以要用绝对路径来使用student对象:

$s1 = new \ncov2019\ahcme\student("11001", "张三");

给命名空间起个别名

    上面的命名空间\ncov2019\wiseduncov2019\ahcme名字太长,经常写的话就很费事,所以打算用个短点的名字,如ahcme。这是可以使用use关键字来给命名空间起个别名:

 关于PHP命名空间的讨论

除了可以使用use语句给命名空间起别名,也可以给常量、函数、类名起个别名:

  关于PHP命名空间的讨论

关于PHP命名空间的讨论

    总之,命名空间就是用来解决不同软件开发团队间常量/函数/类的同名问题。如果遇不到命名冲突问题,完全可以不使用命名空间。

    另外,php的命名空间是从5.3版本才开始的,从个人感觉来看,他的命名空间解决机制没有java和.net的丰富和灵活。从总体来看,php没有多少如淘宝、youtube等大型项目的应用,他的主要应用还是在于中小型项目的快速构建,所以,它在一些复杂项目的管理支持上还是要欠缺一些。

    有问题,请在下方评论区留言。

(2020.3.14 0:48 by whitewin)