PHP命名空间的来由与使用例子

随着你的类库的不断扩展,最后很可能会遇这样一种情况:两个类库使用了相同的类名。不过有史以来,由于要求每个类有唯一的类名,所以不可能在同一个PHP脚本中使用两个同名的类。

随着你的PHP代码库的增长,对之前定义的函数和类名进行修改时风险也更高了,当你试图增加第三方组件或插件时问题更严重,如果存在两个或两个以上的代码集实现了一个“Database”和“User”类会怎么样?

直到目前,唯一的解决办法是使用长的类/函数名,例如Wordpress在每个类和函数名前都使用了前缀“WP_”, Zend Framework使用了极具描述性的命名约定,导致类名非常冗长,如:Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive

命名冲突问题可以使用命名空间来解决,PHP常量、类和函数可以被组合到命名空间库中。

为了说明这个问题的难度,假设你已经创建了一个网站,允许你管理你的图书收藏,而且允许访问者对你个人图书馆中的任何图书做出评论。为了管理评论,你创建了一个名为Library.inc.php的库,其中包含一个名为Clean的类。这个类实现了许多通用的数据过滤器,这些数据过滤器不仅可以用于与图书相关的数据,还可以用于用户评论。例如,下面显示了这个类,它包含一个能够将评论标题第一个词大写的过滤器。这个类如下所示:

class Clean {
	function FilterTitle($text){
  		return ucfirst(trim($text));
 	}
}

不过,由于这是一个健康网站,你希望用户提供的所有数据都通过一个不文明语言过滤器。通过在线搜索,查到一个名为DataCleaner.inc.php的PHP类库,不过你不知道的是,这个类库中包含一个同样名为Clean的类。这个类包含一个函数RemoveProfanity(),它负责将不文明的言语替换为能让人接受的说法。这个类如下所示:

class Clean {
	function RemoveProfanity($text){
  		$badwords=array(
			"idiotic"=>"shortsighted",
  			"moronic"=>"unreasonable",
  			"insane"=>"illogical"
			);
  		return strtr($text,$badwords);
 	}
}

由于非常急切地想要使用这个不文明语言过滤器,你在相关脚本最上面包含了DataCleaner.inc.php文件,后面是另一include语句来包含Library.inc.php:

include Library.inc.php; 
include DataCleaner.inc.php;

然后做一些修改来利用这个不文明语言过滤器,但是将这个应用程序加载到浏览器时,你会遇到以下致命错误消息:

Fatal error:Cannot redeclare class Clean

之所以会得到这个错误,原因在于不能在同一个脚本中使用两个同名的类。从PHP6开始,有一种简单的方法可以解决这个问题,这就是使用命名空间。所要做的只是为各个类指定一个命名空间。为此,需要对各个文件做一处修改。打开Library.inc.php,并把下面这行代码放在该文件最前面:

namespace Library;

类似的,打开DataCleaner.inc.php,在最前面增加以下代码行:

namespace DataCleaner;

然后就可以使用这两个不同的Clean类,而不必担心出现命名冲突。为此,可以实例化各个类,但要在类前面增加命名空间作为前缀,如下例所示:

include Library.inc.php; 
include DataCleaner.inc.php;

$filter = new Library::Clean();
$profanity = new DataFilter::Clean();

在你自己的应用程序中实现PHP6的命名空间特性之前,一定要仔细研究PHP手册,因为命名空间特性的功能和限制可能会有很大的改变。

zgguan.com(it学习网) — 提供最好的 XHTML教程DIV+CSS教程JavaScript教程PHP教程ThinkPHP教程