命名空間的支持版本:PHP 5 > 5.3.0,PHP 7 。php
從廣義上來講,命名空間是一種封裝事物的方法。在不少地方均可以見到這種抽象概念。例如,在操做系統中目錄用來將相關文件分組,對於目錄中的文件來講,它就扮演了命名空間的角色。具體舉個例子,文件 foo.txt 能夠同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 文件。另外,在目錄 /home/greg 外訪問 foo.txt 文件時,咱們必須將目錄名以及目錄分隔符放在文件名以前獲得 /home/greg/foo.txt。這個原理應用到程序設計領域就是命名空間的概念。ide
在PHP中,命名空間用來解決在編寫類庫或應用程序時建立可重用的代碼如類或函數時碰到的兩類問題:函數
PHP 命名空間提供了一種將相關的類、函數和常量組合到一塊兒的途徑。編碼
命名空間經過關鍵字namespace 來聲明。聲明命名空間的語句必須是文件的第一行語句,除了一個之外:declare關鍵字。在聲明命名空間以前惟一合法的代碼是用於定義源文件編碼方式的 declare 語句。另外,全部非 PHP 代碼包括空白符都不能出如今命名空間的聲明以前。同一個命名空間能夠定義在多個文件中,即容許將同一個命名空間的內容分割存放在不一樣的文件中。spa
<?php namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?>
同目錄具備層次結構相似,命名空間也支持指定層次化的命名空間名稱。操作系統
<?php namespace MyProject\Sub\Level; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?>
上面的例子建立了常量MyProject\Sub\Level\CONNECT_OK,類 MyProject\Sub\Level\Connection和函數 MyProject\Sub\Level\connect。.net
PHP還支持在同一個文件中定義不一樣的命名空間,可是很是不建議這種用法,這裏就很少說了。設計
這裏我有一個疑問,上面說命名空間定義必須是文件的第一行代碼,那在一個文件中定義多個命名空間不就是會出現不在第一行的狀況?
針對這個問題試驗了一下,對於一個文件中包含多個命名空間的,必須全部的代碼都在某一個命名空間中,不然就會報Fatal error: No code may exist outside of namespace {} in
的錯誤,對於全局代碼,那就放在全局的命名空間中,相似這樣namespace { }
code
PHP 命名空間中的元素能夠經過三種方式引用,以類名爲例:對象
常量__NAMESPACE__的值是包含當前命名空間名稱的字符串。在全局的,不包括在任何命名空間中的代碼,它包含一個空的字符串。
關鍵字 namespace 可用來顯式訪問當前命名空間或子命名空間中的元素。它等價於類中的 self 操做符。
全部支持命名空間的PHP版本支持三種別名或導入方式:爲類名稱使用別名、爲接口使用別名或爲命名空間名稱使用別名。PHP 5.6開始容許導入函數或常量或者爲它們設置別名。在PHP中,別名是經過操做符 use 來實現的.
<?php namespace foo; use My\Full\Classname as Another; // 下面的例子與 use My\Full\NSname as NSname 相同 use My\Full\NSname; // 導入一個全局類 use ArrayObject; // importing a function (PHP 5.6+) use function My\Full\functionName; // aliasing a function (PHP 5.6+) use function My\Full\functionName as func; // importing a constant (PHP 5.6+) use const My\Full\CONSTANT; $obj = new namespace\Another; // 實例化 foo\Another 對象 $obj = new Another; // 實例化 My\Full\Classname 對象 NSname\subns\func(); // 調用函數 My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // 實例化 ArrayObject 對象 // 若是不使用 "use \ArrayObject" ,則實例化一個 foo\ArrayObject 對象 func(); // calls function My\Full\functionName echo CONSTANT; // echoes the value of My\Full\CONSTANT ?>
注意對命名空間中的名稱(包含命名空間分隔符的徹底限定名稱如 Foo\Bar以及相對的不包含命名空間分隔符的全局名稱如 FooBar)來講,前導的反斜槓是沒必要要的也不推薦的,由於導入的名稱必須是徹底限定的,不會根據當前的命名空間做相對解析。爲了簡化操做,PHP還支持在一行中使用多個use語句。
若是沒有定義任何命名空間,全部的類與函數的定義都是在全局空間,與 PHP 引入命名空間概念前同樣。在名稱前加上前綴 \ 表示該名稱是全局空間中的名稱,即便該名稱位於其它的命名空間中時也是如此。
參考資料:
一、PHP 命名空間