命名空間概述
在PHP中,命名空間用來解決在編寫類庫或應用程式時建立可重用的代碼如類或函數時碰到的兩類問題:
使用者編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。
為很長的標識符名稱(通常是為了緩解第一類問題而定義的)建立一個別名(或簡短)的名稱,提高原始碼的可讀性。
PHP 命名空間提供了一種將相關的類、函數和常量組合到一起的途徑。下面是一個說明 PHP 命名空間文法的樣本:
定義命名空間
雖然任意合法的PHP代碼都可以包含在命名空間中,但只有三種類型的代碼受命名空間的影響,它們是:類,函數和常量。命名空間通過關鍵字namespace 來聲明。如果一個檔案中包含命名空間,它必須在其它所有代碼之前聲明命名空間。另外,與PHP其它的語言特徵不同,同一個命名空間可以定義在多個檔案中,即允許將同一個命名空間的內容分割存放在不同的檔案中。當然你也可以在同一個檔案中定義多個命名空間。
複製代碼 代碼如下:
namespace MyProject;
class MyClass
{
#code...
}
定義子命名空間:與目錄和檔案的關係很象,PHP 命名空間也允許指定層次化的命名空間的名稱。因此,命名空間的名字可以使用分層次的方式定義:
複製代碼 代碼如下:
namespace MyProject\helper\http;
class MyClass
{
#code...
}
在同一個檔案中定義多個命名空間:在同一個檔案中聲明多個命名空間有兩種方式,不過在實際編程實踐中,非常不提倡在同一個檔案中定義多戈命名空間。這種方式的主要用於將多個 PHP 指令碼合并在同一個檔案中。下面列出第一種方法。
複製代碼 代碼如下:
namespace MyProject\helper\http;
class MyClass
{
#code...
}
namespace MyProject\helper\request;
class MyClass
{
#code...
}
不過強烈不建議使用這種方法,可以參考下面的大括弧定義法:
複製代碼 代碼如下:
namespace MyProject\helper\http;
{
class MyClass
{
#code...
}
}
namespace MyProject\helper\request;
{
class MyClass
{
#code...
}
}
PHP 命名空間中的元素使用
在討論如何使用命名空間之前,必須瞭解 PHP 是如何知道要使用哪一個命名空間中的元素的。類名可以通過三種方式引用:
非限定名稱,或不包含首碼的類名稱,例如 $a=new foo(); 或 foo::staticmethod();。如果當前命名空間是 currentnamespace,foo 將被解析為 currentnamespace\foo。如果使用 foo 的代碼是全域的,不包含在任何命名空間中的代碼,則 foo 會被解析為foo。 警告:如果命名空間中的函數或常量未定義,則該非限定的函數名稱或常量名稱會被解析為全域函數名稱或常量名稱。詳情參見 使用命名空間:後備全域函數名稱/常量名稱。
限定名稱,或包含首碼的名稱,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果當前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespace\subnamespace\foo。如果使用 foo 的代碼是全域的,不包含在任何命名空間中的代碼,foo 會被解析為subnamespace\foo。
完全限定名稱,或包含了全域首碼操作符的名稱,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在這種情況下,foo 總是被解析為代碼中的文字名(literal name)currentnamespace\foo。
使用命名空間:別名/匯入
允許通過別名引用或匯入外部的完全限定名稱,是命名空間的一個重要特徵。PHP 命名空間支援 有兩種使用別名或匯入方式:為類名稱使用別名,或為命名空間名稱使用別名。在PHP中,別名是通過操作符 use 來實現的。
注意PHP不支援匯入函數或常量。
複製代碼 代碼如下:
namespace foo;
use My\Full\Classname as Another;
// 下面的例子與 use My\Full\NSname as NSname 相同
use My\Full\NSname;
// 匯入一個全域類
use \ArrayObject;
名稱解析規則
在說明名稱解析規則之前,我們先看一些重要的定義:
非限定名稱Unqualified name:名稱中不包含命名空間分隔字元的標識符,例如 Foo
限定名稱Qualified name:名稱中含有命名空間分隔字元的標識符,例如 Foo\Bar
完全限定名稱Fully qualified name:名稱中包含命名空間分隔字元,並以命名空間分隔字元開始的標識符,例如 \Foo\Bar。 namespace\Foo 也是一個完全限定名稱。
名稱解析遵循下列規則:
對完全限定名稱的函數,類和常量的調用在編譯時間解析。例如 new \A\B 解析為類 A\B。
所有的非限定名稱和限定名稱(非完全限定名稱)根據當前的匯入規則在編譯時間進行轉換。例如,如果命名空間 A\B\C 被匯入為 C,那麼對 C\D\e() 的調用就會被轉換為 A\B\C\D\e()。
在命名空間內部,所有的沒有根據匯入規則轉換的限定名稱均會在其前面加上當前的命名空間名稱。例如,在命名空間 A\B 內部調用 C\D\e(),則 C\D\e() 會被轉換為 A\B\C\D\e() 。
非限定類名根據當前的匯入規則在編譯時間轉換(用全名代替短的匯入名稱)。例如,如果命名空間 A\B\C 匯入為C,則 new C() 被轉換為 new A\B\C() 。
在命名空間內部(例如A\B),對非限定名稱的函數調用是在運行時解析的。例如對函數 foo() 的調用是這樣解析的:
1) 在當前命名空間中尋找名為 A\B\foo() 的函數
2) 嘗試尋找並調用 全域(global) 空間中的函數 foo()。
在命名空間(例如A\B)內部對非限定名稱或限定名稱類(非完全限定名稱)的調用是在運行時解析的。下面是調用 new C() 及 new D\E() 的解析過程: new C()的解析:
在當前命名空間中尋找A\B\C類。
嘗試自動裝載類A\B\C。
new D\E()的解析:
在類名稱前面加上當前命名空間名稱變成:A\B\D\E,然後尋找該類。
嘗試自動裝載類 A\B\D\E。
為了引用全域命名空間中的全域類,必須使用完全限定名稱 new \C()。
Example 名稱解析樣本
複製代碼 代碼如下:
namespace A;
use B\D, C\E as F;
// 函數調用
foo(); // 首先嘗試調用定義在命名空間"A"中的函數foo()
// 再嘗試調用全域函數 "foo"
\foo(); // 調用全域空間函數 "foo"
my\foo(); // 調用定義在命名空間"A\my"中函數 "foo"
F(); // 首先嘗試調用定義在命名空間"A"中的函數 "F"
// 再嘗試調用全域函數 "F"
// 類引用
new B(); // 建立命名空間 "A" 中定義的類 "B" 的一個對象
// 如果未找到,則嘗試自動裝載類 "A\B"
new D(); // 使用匯入規則,建立命名空間 "B" 中定義的類 "D" 的一個對象
// 如果未找到,則嘗試自動裝載類 "B\D"
new F(); // 使用匯入規則,建立命名空間 "C" 中定義的類 "E" 的一個對象
// 如果未找到,則嘗試自動裝載類 "C\E"
new \B(); // 建立定義在全域空間中的類 "B" 的一個對象
// 如果未發現,則嘗試自動裝載類 "B"
new \D(); // 建立定義在全域空間中的類 "D" 的一個對象
// 如果未發現,則嘗試自動裝載類 "D"
new \F(); // 建立定義在全域空間中的類 "F" 的一個對象
// 如果未發現,則嘗試自動裝載類 "F"
// 調用另一個命名空間中的靜態方法或命名空間函數
B\foo(); // 調用命名空間 "A\B" 中函數 "foo"
B::foo(); // 調用命名空間 "A" 中定義的類 "B" 的 "foo" 方法
// 如果未找到類 "A\B" ,則嘗試自動裝載類 "A\B"
D::foo(); // 使用匯入規則,調用命名空間 "B" 中定義的類 "D" 的 "foo" 方法
// 如果類 "B\D" 未找到,則嘗試自動裝載類 "B\D"
\B\foo(); // 調用命名空間 "B" 中的函數 "foo"
\B::foo(); // 調用全域空間中的類 "B" 的 "foo" 方法
// 如果類 "B" 未找到,則嘗試自動裝載類 "B"
// 當前命名空間中的靜態方法或函數
A\B::foo(); // 調用命名空間 "A\A" 中定義的類 "B" 的 "foo" 方法
// 如果類 "A\A\B" 未找到,則嘗試自動裝載類 "A\A\B"
\A\B::foo(); // 調用命名空間 "A\B" 中定義的類 "B" 的 "foo" 方法
// 如果類 "A\B" 未找到,則嘗試自動裝載類 "A\B"
?>
http://www.bkjia.com/PHPjc/788610.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/788610.htmlTechArticle命名空間概述 在PHP中,命名空間用來解決在編寫類庫或應用程式時建立可重用的代碼如類或函數時碰到的兩類問題: 使用者編寫的代碼與P...