在之前的文章中給大家?guī)砹恕对鯓尤ジ愣≒HP類的繼承?(總結(jié)分享)》,其中詳細(xì)介紹了在PHP類中有關(guān)繼承的相關(guān)知識,本篇我們繼續(xù)來看一下PHP命名空間的相關(guān)知識,希望對大家有幫助!
命名空間其實是個抽象的概念,舉個例子,在我們?nèi)粘I钪?,操作系統(tǒng)中目錄用來將相關(guān)文件分組,對于目錄中的文件來說,它就扮演了命名空間的角色。
那么什么是命名空間呢?其實,命名空間可以理解為封裝事物的方法,在PHP中的類、函數(shù)、常量是不能夠同名的,為了不讓他們同名,解決三者的同名問題,所以需要用到命名空間。
在PHP中,命名空間主要用來解決用戶編寫的代碼與PHP內(nèi)部或者第三方的類、函數(shù)、常量之間的命名沖突,文件太多的時候總會有可能命名會重復(fù);還有為很長的標(biāo)識符名稱創(chuàng)建一個很簡短的名稱,這樣的話會提高代碼的可讀性。
那么命名空間是怎樣聲明也就是定義和使用的呢?接下來我們來看一下應(yīng)該如何定義命名空間吧!
定義命名空間
在PHP中任意正確的代碼都可以包含在命名空間中,但是只有類、函數(shù)、常量等類型的代碼才會收到命名空間的影響。
我們通過namespace
關(guān)鍵字來完成命名空間的定義,它的語法格式如下:
namespace 命名空間名;
示例如下:
<?php // 定義代碼在 'named' 命名空間中 namespace named; //在這里可以不使用大括號 // ... 代碼 ... ?>
-
定義兩個命名空間:
<?php namespace MyProject { //這里建議大家使用大括號,這里定義了一個名為MyProject的命名空間 const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace Another { //這里定義了一個名為Another的命名空間 const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } ?>
-
定義子命名空間
PHP中的命名空間與目錄和文件的關(guān)系是很像的,可以允許指定層次化的命名空間名稱。因此,命名空間的名字可以使用分層次的方式來定義,它的語法格式如下:
namespace AppModel; namespace AppControllerHome;
示例如下:
<?php namespace MyProjectSubLevel; //聲明分層次的單個命名空間 const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
在上述事例中,創(chuàng)建了常量 MyProjectSubLevelCONNECT_OK,類 MyProjectSubLevelConnection 和函數(shù) MyProjectSubLevelConnect
-
在同一個文件中,定義多個命名空間
我們有兩種語法格式可以在一個文件中定義多個命名空間,示例如下:
首先就是簡單的語法組合
<?php namespace named; const CONNECT_OK = 1; class className { /* ... */ } namespace names; const CONNECT_OK = 1; class className { /* ... */ } ?>
然后就是大括號{}
<?php namespace named{ const CONNECT_OK = 1; class className { /* ... */ } } namespace names{ const CONNECT_OK = 1; class className { /* ... */ } } ?>
通過上述的介紹,我們已經(jīng)知道了應(yīng)該如何定義命名空間,只是定義命名空間還不夠,我們在PHP中使用它才是比較重要的,那接下來看一下應(yīng)該如何使用命名空間。
使用命名空間
在了解應(yīng)該如何使用命名空間之前,我們應(yīng)該要了解的是在PHP中是怎么知道要是用哪一個命名空間中的元素的,這時候我們就需要知道PHP中命名空間元素訪問的原理了。首先PHP中的我們不太清楚,但是文件系統(tǒng)我們可以總結(jié)出訪問文件的三種方式:
相對文件名、相對路徑名和絕對路徑名。
PHP命名空間的元素只用同樣的原理,例如命名空間下的類名可以通過三種方式引出:
-
非限定名稱,或不包含前綴的類名稱,例如
$a = new test()
或者test
,如果當(dāng)前命名空間是currentnamespace
,那么test將被解析為currentnamespacetest
。如果test的代碼是全局的,不包含任何命名空間中的代碼,那么test會被解析為test。 -
限定名稱,或包含前綴名稱,例如
$a = new subnamespacetest()
,如果當(dāng)前命名空間是currentnamespace
,則 test 會被解析為currentnamespacesubnamespacetest
,如果test的代碼是全局的,不包含任何命名空間中的代碼,那么test會被解析為subnamespacefoo
。 -
完全限定名稱,或包含了全局前綴操作符的名稱,例如
$a = new currentnamespacetest()
,這種情況下,test 總是被解析為代碼中的文字名currentnamespacetest
。
下面是一個使用這三種方式的實例,我們需要兩個 PHP 源文件,分別是 demo.php
和 index.php
,示例代碼如下:
<?php namespace TestBarDemo; const FOO = 1; function foo() {} class foo { public function demo() { echo '命名空間為:TestBarDemo'; } } ?>
<?php namespace FooBar; include 'Demo.php'; const FOO = 2; function foo() { echo 'FooBar 命名空間下的 foo 函數(shù)<br>'; } class foo { static function demo(){ echo '命名空間為:FooBar<br>'; } } /* 非限定名稱 */ foo(); // 解析為 FooBarfoo resolves to function FooBarfoo foo::demo(); // 解析為類 FooBarfoo 的靜態(tài)方法 staticmethod。 echo FOO.'<br>'; // 解析為常量 FooBarFOO /* 限定名稱 */ Demofoo(); // 解析為函數(shù) FooBarDemofoo Demofoo::demo(); // 解析為類 FooBarDemofoo, // 以及類的方法 demo echo DemoFOO.'<br>'; // 解析為常量 FooBarDemoFOO /* 完全限定名稱 */ FooBarfoo(); // 解析為函數(shù) FooBarfoo FooBarfoo::demo(); // 解析為類 FooBarfoo, 以及類的方法 demo echo FooBarFOO.'<br>'; // 解析為常量 FooBarFOO ?>
在上述事例中,我們需要注意的是,訪問任意全局類、函數(shù)或常量,都可以使用完全限定名稱,例如 strlen()
或 Exception
等。
別名、導(dǎo)入
PHP 允許通過別名引用或?qū)氲姆绞絹硎褂猛獠康拿臻g,這是命名空間的一個重要特征。
在PHP中,通過use
關(guān)鍵字和as
配合可以實現(xiàn)命名空間的導(dǎo)入和設(shè)置別名。它的語法格式如下:
use 命名空間 as 別名;
示例如下:
<?php namespace foo; use MyFullClassname as Another; // 下面的例子與 use MyFullNSname as NSname 相同 use MyFullNSname; // 導(dǎo)入一個全局類 use ArrayObject; // 導(dǎo)入一個函數(shù) use function MyFullfunctionName; // 導(dǎo)入一個函數(shù)并定義別名 use function MyFullfunctionName as func; // 導(dǎo)入一個常量 use const MyFullCONSTANT; $obj = new namespaceAnother; // 實例化 fooAnother 對象 $obj = new Another; // 實例化 MyFullClassname 對象 NSnamesubnsfunc(); // 調(diào)用 MyFullNSnamesubnsfunc 函數(shù) $a = new ArrayObject(array(1)); // 實例化 ArrayObject 對象 // 如果不使用 "use ArrayObject" ,則實例化一個 fooArrayObject 對象 func(); // 調(diào)用 MyFullfunctionName 函數(shù) echo CONSTANT; // 打印 MyFullCONSTANT 常量 ?>
其中需要注意的是,導(dǎo)入操作只影響非限定名稱和限定名稱。完全限定名稱由于是確定的,故不受導(dǎo)入的影響。
大家如果感興趣的話,可以點(diǎn)擊《PHP視頻教程》進(jìn)行