Linfinity

Never say never.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

php命名空间

Posted on 2019-01-10 19:11  Linfinity  阅读(150)  评论(0)    收藏  举报

一、命名空间基本介绍

介绍

命名空间用来解决这样的问题:

当项目越来越大,PHP文件会越来越多,再加上多人协同开发,在定义类、函数或者常量时,就不可避免的出现命名冲突,如何解决呢?

 

使用命名空间解决

例如:班里有3个小明,来自不同的地方,如果直接喊小明时,这3个人就会很迷惑,为了避免这种情况,再叫小明时,加上区域名称:东北的小明,河北的小明,湖北的小明;其中,小明前面的区域修饰就是命名空间

 

所以我们在定义类函数常量时在前面加上所属的空间

 

二、命名空间的声明

namespace关键字声明命名空间,一旦使用namespace声明了,就会在当前文件创建一个空间,后面的代码会保存到该空间

 

1、定义命名空间

默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。

命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。语法格式如下:

< ?php  
// 定义代码在 'MyProject' 命名空间中  
namespace MyProject;  
 
// ... 代码 ...  

你也可以在同一个文件中定义不同的命名空间代码,如

说明:非常不建议大家在一个PHP文件中定义多个空间

作为了解即可

< ?php  
namespace MyProject1;  
// MyProject1 命名空间中的PHP代码  
 
namespace MyProject2;  
// MyProject2 命名空间中的PHP代码    
 
// 另一种语法
namespace MyProject3 {  
 // MyProject3 命名空间中的PHP代码    
}  
?>  

在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。

以下代码会出现语法错误:

<html>
<?php
    namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
?>

 

2、子命名空间

与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义,分隔符是\。

例如:

<?php 
namespace php\web; 
define('MESSAGE','hello world'); 
?>

 

3、全局空间  

namespace 后面的代码属于当前空间,namespace之外的空间称之为全局空间类似于:PHP的全局变量

如何使用全局空间的成员呢? 全局空间使用 \ 代替

 

 三、命名空间的使用

 1.非限定名称

使用类函数常量这些成员时如果成员前面没有任何空间修饰就是非限定名称就会在当前空间查找这个成员

 

<?php

namespace php\sub1;

class Car{
	
	
}

$c = new Car;
//由于Car类前没有任何空间修饰,就属于非限定名称,就会在当前命名空间下找Car类。

 

 

2.限定名称

限定名称就是说这个成员属于哪个空间也就是说查找的时候在哪个空间查找

说明:这种方法不太灵活,所以尽量少用

<?php

namespace php\sub1;

class Car{
	
	
}

$c = new sub2\Car;
//相当于php\sub1\sub2\Car

说明:对require_once的疑问

require_once将文件里面的代码执行之后加载过来加载之后导致的结果

虽然代码过来了但是还是存在2个不同的空间:

 

3.完全限定名称

相当于绝对路径的意思

<?php

namespace php\sub1;

class Car{
	
	
}

$c = new \sub2\Car;
//相当于找命名空间sub2下的Car类

 

一个细节: 

类,只在当前空间查找并使用

函数、常量先在当前空间找如果当前空间没有再去全局空间查找

 

四、导入命名空间 

介绍

如果我们在一个空间里面使用其他空间的成员的时候,如果使用完全限定名称,就会导致这类成员的前缀太长了,例如:

<?php

namespace php\sub1;

class Car{
	
	
}

$c = new \pho\sub2\Car;   //前缀太长了

为了解决这样的问题就可以先将需要的类导入到当前空间

空间的导入分为两类

1.空间整体导入:

说明:如果是整体导入,需要导入之后取别名在使用,如果没有取别名,默认以空间最后的成员为别名

<?php

namespace php\sub1;

use php\sub2 as sub2 //use php\sub2;这样导入时默认别名为sub2
class Car{
    
    
}

$c = new \sub2\Car;

 

2.单独导入类、函数、常量

说明php5.6版本之前只能导入类,php5.6之后允许导入函数常量

 

导入类:use 空间\

 

导入函数:use function 空间\函数名

 

导入常量:use const 空间\常量名

 

<?php

namespace php\sub1;

use php\sub2\Car;
use function php\sub2\func1;
use const php\sub2\PIL;


class Car{
	
	
}

$c = new Car;
func1();
echo PIL;

 

 

细节

导入  require_once的区别

require_once先执行再加载,所以Require_once加载之后的结果就是在php文件存在2个空间了空间没有联系的如果想使用其他空间的成员需要导入到当前空间

注意空间是在内存中维护的

 

五、命名空间的动态语言特

 

介绍

我们可以将命名空间保存到变量中,这就体现了命名空间的动态语言特性

 

细节

如果将命名空间保存到变量的话就必须使用完全限定名称

由于在动态的类、函数、常量中,限定名称和非限定名称没有区别,所以前置的\ 可以省略

<?php

namespace php\sub1;



class Car{
	
	
}

$className = 'php\sub2\Car';

new $className;