PHP中的命名空间

1. 命名空间概述
命名空间是一种封装事物,从而避免同名冲突的手段。就如同操作系统中,用目录将文件和文件夹分组,防止文件或文件夹同名冲突一样。

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

  • 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  • 为很长的标识符名称创建一个别名或简短的名称,提高源代码的可读性。
总的来说, PHP 命名空间提供了一种将相关的类、函数和常量组合到一起实现封装的途径。

PHP 在 5.3.0 以后的版本开始支持命名空间。

示例:
<?php
namespace my\name;
class MyClass {}
function 
myfunction() {}
const 
MYCONST 1;
$a = new MyClass;   // 等价于 $a = new \my\name\MyClass;
?>

2. 定义命名空间
只有三种类型的代码受命名空间的影响,它们是:类、函数和常量。

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

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

同一个命名空间可以定义在多个文件中,即允许将同一个命名空间的内容分割存放在不同的文件中。

与目录和文件的关系很像,PHP 命名空间也允许使用层次化的命名空间的名称。因此,命名空间的名称可以使用分层次的方式定义,如:

namespace Admin\Business\UserBusiness;

也可以在同一个文件中定义多个命名空间。在实际编程中,不提倡在同一个文件中定义多个命名空间。这种方式主要用于将多个 PHP 脚本合并到同一个文件中。将全局的非命名空间中的代码与命名空间中的代码组合到一个文件中,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来。


3. namespace关键字和__NAMESPACE__常量
PHP支持两种抽象的访问当前命名空间内部元素的方式:__NAMESPACE__ 魔术常量和namespace关键字。

魔术常量__NAMESPACE__的值是包含当前命名空间名称的字符串。如果是全局的代码(不包括在任何命名空间中的代码),它是一个空的字符串。


4. 使用命名空间(别名和导入)
允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。

PHP中的命名空间支持两种使用别名或导入的方式:为类名称使用别名,或为命名空间名称使用别名。注意PHP不支持导入函数或常量。

在PHP中,别名和导入是通过操作符 use 来实现的。 如:
<?php
namespace Admin\Controller;
use Admin\Business\CompanyBusiness\GetCompany as GC;   
// 作用等同于将该类加载(include或require)到当前脚本文件中,并给该类取了别名GC。

$a = new   GetCompany;
$b = new GC;
$c =  new \Admin\Business\CompanyBusiness\GetCompany;    // 带命名空间的完全限定的类名称(相当于文件系统中的绝对路径)
$d = new GC();
// 上面四个对象实例都是同一个类的。
?>

注意:导入类时, 前导的反斜杠是不允许的,因为导入的类名称必须是完全限定的,PHP并 不会根据当前的命名空间作相对解析,但在创建对象时,如果使用带命名空间的类名称或全局的类(如PHP自身的类Exception),必须加上前导的反斜杠。
在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜线是不必要的。

5. 全局空间

如果没有定义任何命名空间,所有的类、函数和常量的定义都是在全局空间。在名称前加上反斜杠前缀\,表示该名称是全局空间中的名称。

示例:

<?php
namespace A\B\C;
/* 这个函数是 A\B\C\fopen */
function fopen() {     // 命名空间中自定义的fopen函数
     
/* ... */
     
$f = \fopen(...); // 调用全局的fopen函数(即PHP自身内置的fopen函数)
     
return $f;

?>

6. 名称解析规则

在命名空间中,当遇到一个非限定的类、函数或常量名称时,会使用不同的优先策略对名称进行解析:

  • 类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称。
  • 对于函数和常量来说,如果当前命名空间中不存在该函数或常量,会退而使用全局空间中的函数或常量。

非限定名称: 名称中不包含命名空间分隔符的标识符,如  Foo。 限定名称: 名称中含有命名空间分隔符的标识符,如  Foo\Bar。 完全限定名称: 名称中包含命名空间分隔符,并以命名空间分隔 符开始的标识符,如\ Foo\Bar或\Exception 。  namespace\Foo  也是一个完全限定名称。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值