掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流

成都創(chuàng)新互聯(lián)公司于2013年開始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站建設(shè)、成都網(wǎng)站制作網(wǎng)站策劃,項目實(shí)施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元大石橋做網(wǎng)站,已為上家服務(wù),為大石橋各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220
舉個簡單的例子,文件 foo.txt 可以同時在目錄 /home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 文件。另外,在目錄 /home/greg 外訪問 foo.txt 文件時,我們必須將目錄名以及目錄分隔符放在文件名之前,例如 /home/greg/foo.txt。這個原理應(yīng)用到程序設(shè)計領(lǐng)域就是命名空間的概念。
php 中命名空間(namespace)是在 PHP5.3 中加入的,如果你了解過 C++ 的話,那命名空間就不算什么新事物了。不過命名空間在 PHP 當(dāng)中還是相當(dāng)重要的。
PHP 命名空間可以解決以下兩類問題:
雖然任意合法的 PHP 代碼都可以包含在命名空間中,但只有類(包括抽象類和 traits)、接口、函數(shù)和常量等類型的代碼受命名空間的影響。
命名空間的定義需要通過關(guān)鍵字 namespace 來聲明,語法格式如下:
namespace 命名空間名;
【示例】下面我們來演示一下如何定義了命名空間:
在聲明命名空間之前除了用于定義源文件編碼方式的 declare 語句外,所有非 PHP 代碼(包括空白符)都不能出現(xiàn)在命名空間聲明之前。
另外,與 PHP 其它的語言特征不同,同一個命名空間可以定義在多個文件中,即允許將同一個命名空間的內(nèi)容分割存放在不同的文件中。
與目錄和文件的關(guān)系很象,PHP 中的命名空間也允許指定層次化的命名空間名稱。因此,命名空間的名字可以使用分層次的方式定義:
namespace App\Model;
namespace App\Controller\Home;
【示例】定義一個子命名空間:
在一個文件中也可以定義多個命名空間,在同一文件中定義多個命名空間有兩種語法形式,下面通過示例演示一下:
【示例】定義多個命名空間——簡單組合語法。
【示例】定義多個命名空間——大括號
{ }語法。
在實(shí)際的編程實(shí)踐中,并不提倡在同一個文件中定義多個命名空間。定義多個命名空間主要用于將多個 PHP 腳本合并在同一個文件中。在定義多個命名空間時建議使用大括號形式的語法。
將全局的非命名空間中的代碼與命名空間中的代碼組合在一起,只能使用大括號形式的語法,同時全局代碼必須用一個不帶名稱的 namespace 語句加上大括號括起來,如下所示:
在討論如何使用命名空間之前,必須了解 PHP 是如何知道要使用哪一個命名空間中的元素的。我們可以將 PHP 命名空間與文件系統(tǒng)作一個簡單的類比。在文件系統(tǒng)中訪問一個文件有三種方式:
PHP 命名空間中的元素使用同樣的原理。例如,命名空間下的類名可以通過三種方式引用:
$a=new foo(); 或 foo::staticmethod();。如果當(dāng)前命名空間是 currentnamespace,那么 foo 將被解析為 currentnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會被解析為 foo。 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果當(dāng)前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespace\subnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會被解析為 subnamespace\foo。 $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在這種情況下,foo 總是被解析為代碼中的文字名 currentnamespace\foo。警告:如果命名空間中的函數(shù)或常量未定義,則該非限定的函數(shù)名稱或常量名稱會被解析為全局函數(shù)名稱或常量名稱。
下面是一個使用這三種方式的實(shí)例,我們需要兩個 PHP 源文件,分別是 demo.php 和 index.php,示例代碼如下:
';
}
class foo
{
static function demo(){
echo '命名空間為:Foo\Bar
';
}
}
/* 非限定名稱 */
foo(); // 解析為 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::demo(); // 解析為類 Foo\Bar\foo 的靜態(tài)方法 staticmethod。
echo FOO.'
'; // 解析為常量 Foo\Bar\FOO
/* 限定名稱 */
Demo\foo(); // 解析為函數(shù) Foo\Bar\Demo\foo
Demo\foo::demo(); // 解析為類 Foo\Bar\Demo\foo,
// 以及類的方法 demo
echo Demo\FOO.'
'; // 解析為常量 Foo\Bar\Demo\FOO
/* 完全限定名稱 */
\Foo\Bar\foo(); // 解析為函數(shù) Foo\Bar\foo
\Foo\Bar\foo::demo(); // 解析為類 Foo\Bar\foo, 以及類的方法 demo
echo \Foo\Bar\FOO.'
'; // 解析為常量 Foo\Bar\FOO
?>
運(yùn)行結(jié)果如下:
Foo\Bar 命名空間下的 foo 函數(shù)
命名空間為:Foo\Bar
2
Foo\Bar\Demo 命名空間下的 foo 函數(shù)
命名空間為:Foo\Bar\Demo
1
Foo\Bar 命名空間下的 foo 函數(shù)
命名空間為:Foo\Bar
2
注意:訪問任意全局類、函數(shù)或常量,都可以使用完全限定名稱,例如 \strlen() 或 \Exception 等。
PHP 允許通過別名引用或?qū)氲姆绞絹硎褂猛獠康拿臻g,這是命名空間的一個重要特征。這有點(diǎn)類似于在類 unix 文件系統(tǒng)中可以創(chuàng)建對其它的文件或目錄的符號連接。
使用 use 關(guān)鍵字可以實(shí)現(xiàn)命名空間的導(dǎo)入,從 PHP5.6 開始允許導(dǎo)入函數(shù)和常量,并為它們設(shè)置別名。語法格式如下:
use namespace;
在 PHP 中,別名是通過操作符 use 與 as 來實(shí)現(xiàn)的,語法格式如下:
use 命名空間 as 別名;
【示例】使用 use 操作符導(dǎo)入和使用別名。
注意:對命名空間中的名稱(包含命名空間分隔符的完全限定名稱,如 Foo\Bar ,以及相對的不包含命名空間分隔符的全局名稱,如 FooBar)來說,前導(dǎo)的反斜杠是不必要的也是不推薦的,因為導(dǎo)入的名稱必須是完全限定的,不會根據(jù)當(dāng)前的命名空間作相對解析。
為了簡化操作,PHP 還支持在一行中導(dǎo)入多個命名空間,中間使用
,隔開,示例代碼如下:
導(dǎo)入操作是編譯執(zhí)行的,但動態(tài)的類名稱、函數(shù)名稱或常量名稱則不是。
另外,導(dǎo)入操作只影響非限定名稱和限定名稱。完全限定名稱由于是確定的,故不受導(dǎo)入的影響。
PHP 支持兩種抽象的訪問當(dāng)前命名空間內(nèi)部元素的方法,__NAMESPACE__ 魔術(shù)常量和 namespace 關(guān)鍵字。
__NAMESPACE__ 常量的值是包含當(dāng)前命名空間名稱的字符串。在全局的,不包括在任何命名空間中的代碼,它是一個空的字符串。示例代碼如下:
運(yùn)行結(jié)果如下:
App\Controller\Home
namespace 關(guān)鍵字可用來顯式訪問當(dāng)前命名空間或子命名空間中的元素,它等價于類中的 self 操作符。示例代碼如下:
在說明名稱解析規(guī)則之前,我們先來看看命名空間名稱的定義:
名稱解析遵循下列規(guī)則:

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流