php命名空间简介

命名空间(名字空间)

1、 什么是命名空间?

什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。好抽象,看不懂,其实他的设计思想其实就是来自我们的操作系统,对于目录中的文件来说,它就扮演了命名空间的角色,一个目录就是一个空间。
类比过来,php中的合法代码仿佛就是目录中的文件,如果我们没有显示的定义当前的命名空间,那么,所有的代码就默认被放在了全局空间中。

2、 命名空间中的一些基本概念?

2.1、非限定名称,或不包含前缀的类名称

例如 $a=new foo(); 或 foo::staticmethod();如果当前命名空间是currentnamespace,foo 将被解析为 currentnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。

对于类而言,如果当前命名空间中不存在该类,那么就需要尝试进行自动加载,如果自动加载函数还没有加载到的话,就报错:

对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。

2.2、限定名称,或包含前缀的名称

例如 $a = new subnamespacefoo(); 或 subnamespacefoo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespacesubnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespacefoo。

2.3、完全限定名称,或包含了全局前缀操作符的名称

例如, $a = new currentnamespacefoo(); 或currentnamespacefoo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespacefoo。

3、 那些类型的代码会受到命名空间的影响?

虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。我们可以看出,只有那些一旦定义就不能改变的代码,才会收到命名空间的影响

4、 命名空间能够解决什么问题?

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

4.1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
4.2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

5、 怎么定义命名空间及其子命名空间?

使用namespace关键字定义命名空间,声明命名空间的时候,第一个命名空间,前面不能够有任何代码,特别注意一下,是第一个namespace前面。之所以这么说是因为,php支持在同一个php脚本中出现多个命名空间。这里列出来常见的几种错误:

错误1、报错信息设置在了namespace之前:

**错误2、

注意,这样写是不会报错的:

错误3、php脚本中出现了bom头信息,同样会报错

报错信息如下:

但是,下面这样写是不会报错的:

Ps:很多地方都没有说明白,命名空间前面不能出现任何代码,指的是第一个命名空间,这里和明显,namespace Hotkeypower之前,已经有echo输出了

6、 如何在同一个文件定义多个命名空间?

写法1:

addComment('You Are Beautiful');?>

这是其中的一种写法,但是我们并不推荐这种写法,甚至我们也不推荐在同一个文件中定义多个命名空间,但是有些事情我们需要知道,但是我们没有必要这样用。如果一定要在一个文件中定义多个命名空间,那么我比较推荐使用这种写法。

写法2:

addComment('You Are Beautiful');    }?>

上面namespace后面的一对花括号中出现的代码,就代表一个命名空间。这里用花括号,进行了显示分割,更加清楚。而第一种写法是代码出现在哪一个命名空间下面,就默认是该命名空间中的代码,不是很容易辨识。

7、 别名/导入的作用究竟是什么?

其实就是use关键字的用法,如果我们查询手册,手册会告诉我们,所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名。PHP 5.6开始允许导入函数或常量或者为它们设置别名。

但是,这究竟怎么用呢?
我的疑惑:长久以来,我一直以为使用use关键字,就是代替include或者require的作用,将指定的类、函数、接口导入到当前脚本中,而且在导入的使用可以起一个别名,用来简化,but,这样的理解是错误的。

举个例子:在/home/www下有两个文件,iredpure.php, hotkeypower.php

addComment('You Are Beautiful');?>

然而却报错了,说是在当前的执行脚本中,并没有发现IredpureComment类。但是我不是使用use将Iredpure这个命名空间给导过来了么?所以,我理解的别名/导入是有问题的。

ps:前导的反斜杠是不必要的也不推荐的,因为导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析。

在手册上面查找发现了下面的一句话:
The statement does not load the class file. You have to do this with the statement or by using an autoload function
大概意思是说,使用use并不会加载类文件,你不得不使用require声明或者是使用自动加载函数来引入类文件。

所以,个人认为use的真正做种是在于使用别名。还是举个例子来说明一下use的用法:
我们新建一个文件/home/www/cuk.php,代码如下:

addComment('test from hotkeypower');    $iredpureComment = new \Iredpure\Comment();    $iredpureComment->addComment('test from iredpure');?>

而/home/www/hotkeypower.php的代码如下:

而/home/www/iredpure.php的代码如下:

我们引入use之后,cuk.php的代码进行了变更,代码如下:

addComment('test from hotkeypower');    $iredpureComment = new IredComment();    $iredpureComment->addComment('test from iredpure');?>

执行之后,会得到想要的结果

8、 命名空间的解析规则是什么?

完全限定名称:没有什么好讲的,类似于绝对路径,限定名称和非限定名称,都是基于上下文的环境,在编译的时候,在调用的类、函数、常量前添加当前的命名空间完成的。

类:
AliPay.class.php脚本

MobileAliPay.class.php

函数、常量

参考文献:
http://php.net/manual/zh/language.namespaces.php

关键字:php


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部