PHP命名空間

一、什麼是命名空間php

命名空間是一種特殊的做用域,它包含處於該做用域下的標識符,同時它自己也是一種標識符。html

能夠把命名空間與操做系統的目錄對應起來。一個命名空間至關於一個目錄,命名空間裏的類,函數,常量,至關於目錄裏的文件。同一個目錄(命名空間)裏的文件名不能相同,可是不一樣的目錄裏能夠有相同名字的文件。框架

二、使用命名空間爲了解決什麼問題?函數

. 解決名字衝突,好比定義了一個類,正好這個類與PHP內部的類或是include進來的一個類庫裏的類重名了。spa

. 提升代碼可讀性,命名空間有一個別名功能,它能夠幫你給一個長達十幾個字符的類名起一個別名,從而縮短代碼,也不用擔憂與其餘空間的命名衝突。操作系統

三、哪一些代碼會受命名空間的影響。3d

三類:類、函數、常量。只有它們兄弟三受影響,其餘的該幹嗎,還幹嗎去。說到常量,php 5.3之後可使用const關鍵字來定義常量,5.3這前使用define,命名空間只對const關鍵字有效。code

四、命名空間如何定義htm

<?php
namespace MyProject;

const CONNECT_OK = 1;//php5.3之後
class Connection { /* ... */ }
function connect() { /* ... */  }
?>
<?php
namespace MyProject\Sub\Level;

const CONNECT_OK = 1;//php5.3之後
class Connection { /* ... */ }
function connect() { /* ... */  }
?>

使用 `namespace 空間名` 來申明一個空間,在namespace以前除了declare語句不能有任何其餘php語句,同時也不能有任何非php代碼,連空格都不能有。blog

如下爲錯誤的形式:

<?php
$a = 1;
namespace MyProject;
?>
//Fatal error: Namespace declaration statement has to be the very first statement in the script...
html//也就是說<\?php要頂格寫,上面不能有任何代碼和空格。
<?php
namespace MyProject;
?>
//Fatal error: Namespace declaration statement has to be the very first statement in the script...

 另外同一個命名空間是能夠定義在多個文件中,這對於組織框架是很是有用的。即以同一個namespace MyProject;開頭的文件,它們是同一個命名空間。因此注意文件之間可不要有相同的類/函數/常量名哦。

固然同一個文件也能夠定義多個命名空間,不過很是不建議這樣作的。(瞭解同一個文件定義多個命名空間

五、命名空間如何使用
命名空間有三種使用形式:

. 非限定名稱 -- 沒有使用任何的\分割符,直接使用類/函數/常量名,如:new Foo(); foo(); echo FOO; 當文件有使用命名空間時,

<?php
namespace MyObject;
new Foo(); // 調用MyObject\Foo();
foo(); //調用MyObject\Foo();
echo FOO; //調用MyObject\FOO;

當文件沒有使用命名空間時,直接調用全局的類/函數/常量。
            
. 非徹底限定名稱 -- 不是以\分割符開頭,如 new Sub\Foo(); 這種形式與非限定名稱方式同樣。

<?php
namespace MyObject;
new Sub\Foo(); //調用MyObject\Sub\Foo();

. 徹底限定名稱 -- 以\分割符開頭的方式,至關於操做系統裏的絕對地址。如 new \OtherNS\Foo();

<?php
namespace MyObject;
new \OtherNS\Foo(); //調用\OtherNs\Foo(); 無論MyObject命名空間。

Tip: 對於函數和常量,還有一個特殊的地方(後備全局函數/常量)。

<?php
namespace MyObject;
funcname(); //若是MyObject\Funcname存在則調用MyObject\Funcname(),不然試着調用\funcname();
echo FOO; //同上。

對於類,也有一個特殊的地方。

<?php
namespace MyObject;
new Foo(); //若是MyObject\Foo存在,調用之,若是不存在,調用__autoload試着加載MyObject\Foo類進來。注意對於類是不會去自動去調用全局做用域下的類的。

use的使用:

以前說了,命名空間還有一個用途-取別名。

<?php
namespace MyObject;
use OtherNS\Sub as Other;
use OtherNS\Sub2; //至關於use OtherNS\Sub2 as Sub2;
use /MyClass;

new Foo(); //調用MyObject\Foo();
new Other\Foo(); //調用 \OtherNS\Sub\Foo();
new Sub2\Foo(); //調用\OtherNS\Sub2\Foo();
new MyClass(); //調用\MyClass();
         

六、動態命名空間

動態老是能讓人摸不着頭腦,然而又帶來靈活性。命名空間一樣可使用動態語言特色,但要注意因爲直接調用命名空間是編譯時解析的,而動態特徵並不是編譯時解析。因此必定要加前綴。如:

<?php
namespace MyObject\Sub;
new Foo(); //調用 MyObject\Sub\Foo(), 編譯時已經解析成MyObject\Sub\Foo
$a = 'Foo';
new $a(); //調用的是\Foo(),而不是MyObject\Sub\Foo()
$b = 'MyObject\Sub\Foo'; //等價於 \MyObject\Sub\Foo
new $b(); //調用MyObject\Sub\Foo()
//若是使用雙引號,要用\\,如 $a = "\\MyObject\\Sub";


附1:同一個文件定義多個命名空間
方法有兩種:

<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
?> 

方法一,記流水賬。

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { //全局

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}
?> 

方法二,使用大括號把同一個命名空間的代碼放在大括號裏。這種方法,要求在大括號外不能有任何除了declare以外的代碼。對於全局做用域的代碼使用沒有空間名的大括號包圍起來。

參考:php手冊

相關文章
相關標籤/搜索