一、什麼是命名空間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";
<?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手冊