PHP命名空间

问题引出:通常用include包含文件的时候,包含的文件中包含同名的类(包括trait)、接口、函数、常量,比如下面的例子:

运行C.php会出错,因为在同一个文件中包含了相同的类名的类

使用命名空间的意义:可以理解为--->使用类似文件系统分级的形式,在定义类或者函数的时候,指定该类或者该函数所在的文件目录即可

按照上面的理解,先假设有一个类名为Test的类在dir1目录下,另外一个类名也为Test的类在dir2目录下,然后我们在使用其中dir1下的Test类的时候,在类名前面要加上dir1,以dir1\Test的形式实例化;同样,如果要使用dir2下的Test类的时候,就在类名前加上dir2,以dir2\Test的形式实例化。

上面的dir1或dir2就是PHP中的命名空间,命名空间的层级结构(方便理解的话,可以理解为层级结构)使用反斜线(\),也就是windows下的文件系统的分隔符来分隔。

上面的例子代码如下:

 

这样运行C.php就不会出错了,因为两个同名的类存在不同的命名空间,所以不会产生冲突

 

到这里,其实命名空间的原理已经讲清楚了。但是每次实例画一个类的时候,都写那么一长串命名空间,比较麻烦,所以可以使用关键字use,在实例画一个类的之前,先使用use将这个类的完整命名空间及类型指明,然后就可以直接使用类名实例化对象了。比如下面的例子

 

这个时候实例化的是dir1命名空间下的Test类,如果又想导入dir2命名空间下的Test类,再使用use dir2\Test的就会出现最初说的那个问题-->同一个作用域,有两个完全相同的类名,出错。

解决方法是在use命名空间下的类之后,给该类取一个别名,之后使用别名来实例化类就可以了,如下面的例子

 

以上的对于类的用法同样也适用于函数、接口、常量。

但是要注意是,

在使用use导入类或者接口的时候,格式为use  namespace\className ,use 后面直接加上命名空间以及类名或者接口名即可。

在使用use导入函数的时候,格式为use  function  namespace\funcName ,use 后面要加上关键字function才行。

在使用use导入常量的时候,格式为use  const  namespace\funcName ,use 后面要加上关键字const才行。

 

命名空间分为全局空间和命名空间,使用namespace声明的空间称为命名空间,如上面的A.php中的dir1命名空间和B.php中的dir2命名空间。而没有在脚本中指定命名空间的时候,就属于全局空间,如C.php。

所以   以上的内容是在全局空间去调用命名空间的类或者函数。

看下面这个例子:

这个例子中,x.php中的Test类因为没有使用namespace声明命名空间,所以Test属于全局空间,访问全局访问全局空间的类时,要使用"\",再加上要实例化的类,"\"可以理解为“根目录”。

注意这里很容易产生误解,比如上图中的y.php中,先声明了index的命名空间,然后在将x.php包含进来,此时不要认为x.php中的内容就变成了index命名空间中声明的了,正确的理解是,x.php中的内容仍旧是在x.php中定义,不可以理解为将x.php中的代码粘贴到y.php中index命名空间下。

还有一个要注意的是,对于类来说,使用全局空间的类,要使用反斜线"\",如果不加反斜线,解释器就理解为实例化在当前命名空间中定义的类,如果当前命名空间未定义该类,则直接报错,停止运行;

在使用全局的函数或者常量的时候,可以不用加"\",通常是这个过程,首先,会在当前的命名空间中寻找是否定义了该函数或者常量,如果定义了,则直接只用命名空间中的函数或者常量,不再往外层继续寻找;如果当前的命名空间中没有定义该常量或者函数时,就会去寻找全局空间,也就是"\"中是否存在该函数或者常量,如果存在,就是用全局空间中的该函数或者常量,如果不存在,则报错。结合上面一个例子和下面这个例子理解。

 

posted @ 2017-12-31 16:07  寻觅beyond  阅读(303)  评论(0编辑  收藏  举报
返回顶部