[初级] PHP 5.3中的命名空间:你用过了么?

为何咱们须要命名空间?

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

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

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

如何定义命名空间?

    默认状况下,全部常量、类和函数名都放在全局空间下,就和PHP支持命名空间以前同样。

    在PHP文件的顶部使用一个关键字namespace就能够定义命名空间,它必须是第一个命令(declare除外),在它前面不能出现非PHP代码、HTML或空格。如:
< ?php  
// define this code in the 'MyProject' namespace  
namespace MyProject;  
 
// ... code ...
     这一行下面的代码都是指定给MyProject命名空间的,为相同代码块嵌套命名空间或定义多个命名空间是不可能的,若是你真这样干,只有最后一个命名空间才能识别,但你能够在同一个文件中定义不一样的命名空间代码,如:
< ?php  
namespace MyProject1;  
// PHP code for the MyProject1 namespace  
 
namespace MyProject2;  
// PHP code for the MyProject2 namespace  
 
// Alternative syntax  
namespace MyProject3 {  
 // PHP code for the MyProject3 namespace  
}  
?>
     尽管这么干是能够的,但我建议你不要这么作,最好仍是每一个文件中只定义一个命名空间,省得把你弄糊涂了。

子命名空间

PHP容许定义具备层次的命名空间以便库可以细分,子命名空间使用一个反斜线字符(\)分隔,如:
◆MyProject\SubName
◆MyProject\Database\MySQL
◆CompanyName\MyProject\Library\Common\Widget1

调用命名空间代码

在lib1.php文件中咱们使用App\Lib1 namespace命名空间定义了一个常量、一个函数和一个类,如:
lib1.php
< ?php  
// application library 1  
namespace App\Lib1;  
 
const MYCONST = 'App\Lib1\MYCONST';  
 
function MyFunction() {  
 return __FUNCTION__;  
}  
 
class MyClass {  
 static function WhoAmI() {  
  return __METHOD__;  
 }  
}  
?>

如今咱们能够在另外一个PHP文件包括这段代码,如: php

myapp.php
< ?php  
header('Content-type: text/plain');  
require_once('lib1.php');  
 
echo \App\Lib1\MYCONST . "\n";  
echo \App\Lib1\MyFunction() . "\n";  
echo \App\Lib1\MyClass::WhoAmI() . "\n";  
?>
    在myapp.php中并无定义命名空间,所以这段代码存在全局空间中,任何对MYCONST、MyFunction和MyClass的直接引用都会失败,由于它们存在于App\Lib1命名空间中,为了调用lib1.php中的代码,咱们能够在\App\Lib1命名空间前添加前缀定义一个彻底合格的名称,下面是我载入myapp.php时的输出结果:

App\Lib1\MYCONST    
App\Lib1\MyFunction    
App\Lib1\MyClass::WhoAmI  app

    彻底合格名称能够变得很长,定义长名称,如App-Lib1-MyClass,有一些明显的好处。