本文笔者在深圳逛街的时候突然想到的...这两天就有想写几篇关于命名空间定义的博客,所以回家到之后就奋笔疾书的写出来发布了
为什么我们需要定名空间?
随着你的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文件包含这段代码,如:
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-Lib1-MyClass,有一些显著的利益。
文章结束给大家分享下程序员的一些笑话语录: 人在天涯钻,哪儿能不挨砖?日啖板砖三百颗,不辞长做天涯人~