命名空間

命名空間是一種封裝事物的方法焙蚓,在php中鳖轰,可以看做是組織代碼的一種形式遣疯。例如雄可,在操作系統(tǒng)中用目錄來把不同的文件分組,這樣在不同的目錄下可以存在相同文件名缠犀,目錄就相當(dāng)于“命名空間”数苫。

命名空間解決的問題

1、用戶編寫的代碼與PHP內(nèi)部的類/函數(shù)/常量或第三方類/函數(shù)/常量之間的名字沖突辨液。比如:用戶定義了一個函數(shù) is_numeric(),如果在代碼中定義一個命名空間namespace user,用戶在調(diào)用時加上命名空間\user\is_numeric()就可以調(diào)用自己的函數(shù)了虐急。
2、為很長的標(biāo)識符名稱創(chuàng)建一個簡短的別名滔迈,提高源代碼的可讀性止吁。栗子:隨著項(xiàng)目的擴(kuò)大,類名可能會很長燎悍,例如A_B_C_D敬惦,如果使用命名空間,就可以這樣用间涵,在D的類里面定義命名空間:namespace \A_B_C_,在定義D的時候仁热,類名就可以直接寫D。

定義命名空間

用關(guān)鍵字namespace關(guān)鍵字聲明勾哩,如果一個文件中包含命名空間抗蠢,它必須在其他所有代碼之前聲明,declare關(guān)鍵字除外思劳。同一個命名空間可以定義在多個文件中迅矛,即允許將同一個命名空間的內(nèi)容分割存放在不同的文件中。
tips:如果用define()定義命名空間的常量潜叛,需要在變量名稱前加上命名空間秽褒,栗子:define('test\HELLO', 'Hello world!');表示在命名空間test下定義常量HELLO,如果不加命名空間,表示在全局范圍內(nèi)定義常量威兜。
在使用一個變量時销斟,如果變量名前不添加任何命名空間,表示該變量是當(dāng)前文件命名空間的變量椒舵;變量名前加\蚂踊,表示全局范圍的變量,栗子:
<pre>
namespace NS;
define(NAMESPACE .'\foo','111’); //在當(dāng)前命名空間定義常量foo
define('foo','222’);//全局范圍定義常量foo
echo foo; // 111笔宿,默認(rèn)取當(dāng)前命名空間的常量
echo \foo; // 222犁钟,取全局范圍的常量
echo \NS\foo // 111. 去NS命名空間的常量
echo NS\foo // 報(bào)錯棱诱,因?yàn)椴皇且診開頭,表示取\NS\NS\foo涝动,這個常量沒有被定義迈勋。
</pre>

定義子命名空間

類似文件系統(tǒng)中的文件子目錄,命名空間也可以分層醋粟,栗子:namespace A\B\C,子命名空間的好處只是更好的表達(dá)代碼的層級關(guān)系靡菇,用法和普通的命名空間沒有區(qū)別,和所謂的“父空間”并沒有關(guān)系昔穴,\A\B\C和\A\B沒有關(guān)系镰官。

同一個文件中定義多個命名空間:
簡單組合方式,在命名空間后直接寫代碼吗货,栗子:
<pre>
namespace MyProject;

const CONNECT_OK = 1;
class Connection { }
function connect() { }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { }
function connect() { }
</pre>
大括號方式泳唠,栗子:
<pre>
namespace MyProject {

const CONNECT_OK = 1;
class Connection { }
function connect() { }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { }
function connect() { }
}
</pre>

使用命名空間

1、不包含前綴宙搬,例如 $a=new foo(); 或 foo::staticmethod();笨腥。如果當(dāng)前命名空間是 currentnamespace,foo 將被解析為 currentnamespace\foo勇垛。
2脖母、包含前綴: $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果當(dāng)前的命名空間是 currentnamespace闲孤,則 foo 會被解析為 currentnamespace\subnamespace\foo谆级。
3、包含全局前綴:例如讼积, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();肥照。

命名空間和動態(tài)語言的關(guān)系

php中有一些魔術(shù)方法,例如:METHOD勤众、CLASS等舆绎,這些方法的輸出結(jié)果和代碼所在的位置有關(guān),如果想用這些魔術(shù)方法輸出類所在的命名空間们颜,定義類的實(shí)例的時候要把命名空間前綴加上吕朵,否則不會打印出命名空間的信息。栗子:
<pre>
namespace namespacename;
class classname
{
function __construct()
{
echo METHOD,"\n";
}
}
function funcname()
{
echo FUNCTION,"\n";
}
const constname = "namespaced";

$a = 'classname';
$obj = new $a; //輸出classname::__construct窥突,因?yàn)槎x的時候沒有加上namespacename前綴
$b = 'funcname';
$b(); // 同理努溃,只輸出funcname
echo constant('constname'), "\n"; // 只輸出global

$a = '\namespacename\classname';
$obj = new $a; // 定義的時候加上前綴,因此打印出 namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // 同樣打印出namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // 輸出 namespacename\funcname
$b = '\namespacename\funcname';
$b(); // 同樣輸出 namespacename\funcname
echo constant('\namespacename\constname'), "\n"; //輸出常量的時候不會輸出命名空間信息
echo constant('namespacename\constname'), "\n"; //輸出 namespaced
</pre>

namespace關(guān)鍵字

關(guān)鍵字 namespace 可用來顯式訪問當(dāng)前命名空間或子命名空間中的元素阻问。它等價(jià)于類中的 self 操作符茅坛。栗子:
namespace MyProject;//定義當(dāng)前命名空間是MyProject
namespace\func(); // 調(diào)用函數(shù)MyProject\func()

__NAMESPACE__常量

常量NAMESPACE的值是包含當(dāng)前命名空間名稱的字符串。在全局的则拷,不包括在任何命名空間中的代碼贡蓖,它包含一個空的字符串。

使用命名空間:別名/導(dǎo)入

如果我們想在當(dāng)前文件引用另外一個文件的命名空間煌茬,而另外一個命名空間很長斥铺,如果每用一次那個空間類都要寫很長的類名,這樣就會使代碼很難看坛善,命名空間有個特征:允許通過別名引用或?qū)胪獠康耐耆薅Q晾蜘,類似于類unix文件系統(tǒng)中可以創(chuàng)建對其他的文件或目錄的軟連接。

所有支持命名空間的PHP版本支持三種別名或?qū)敕绞剑簽轭惷Q使用別名眠屎、為接口使用別名或?yàn)槊臻g名稱使用別名剔交。PHP 5.6開始允許導(dǎo)入函數(shù)或常量或者為它們設(shè)置別名。

別名是通過操作符 use 來實(shí)現(xiàn)的改衩,栗子:
<pre>
namespace foo;
use My\Full\Classname as Another; //引入My\Full\Classname并起個別名Another

use My\Full\NSname;//相當(dāng)于use My\Full\NSname as NSname

use ArrayObject;// 導(dǎo)入一個全局類

use function My\Full\functionName;//導(dǎo)入一個方法

use function My\Full\functionName as func;//導(dǎo)入一個方法并起個別名

use const My\Full\CONSTANT;//導(dǎo)入一個常量

$obj = new namespace\Another; // 實(shí)例化 foo\Another 對象
$obj = new Another; // 實(shí)例化 My\Full\Classname 對象
NSname\subns\func(); // 調(diào)用函數(shù) My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 實(shí)例化 ArrayObject 對象岖常,如果不使用 "use \ArrayObject" ,則實(shí)例化一個 foo\ArrayObject 對象
func(); //調(diào)用方法My\Full\functionName
echo CONSTANT; // 輸出常量My\Full\CONSTANT
</pre>

后備全局函數(shù)/常量

在一個命名空間中葫督,當(dāng) PHP 遇到一個非限定的類竭鞍、函數(shù)或常量名稱時,它使用不同的優(yōu)先策略來解析該名稱橄镜。類名稱總是解析到當(dāng)前命名空間中的名稱偎快。栗子:
<pre>
namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception('hi'); // $a 是類 A\B\C\Exception 的一個對象
$b = new \Exception('hi'); // $b 是類 Exception 的一個對象

$c = new ArrayObject; // 致命錯誤, 找不到 A\B\C\ArrayObject 類
</pre>
對于函數(shù)和常量來說,如果當(dāng)前命名空間中不存在該函數(shù)或常量洽胶,PHP 會退而使用全局空間中的函數(shù)或常量晒夹。

名稱解析的規(guī)則

1、對完全限定名稱的函數(shù)姊氓,類和常量的調(diào)用在編譯時解析丐怯。例如 new \A\B 解析為類 A\B。
2他膳、所有的非限定名稱和限定名稱(非完全限定名稱)根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時進(jìn)行轉(zhuǎn)換响逢。例如,如果命名空間 A\B\C 被導(dǎo)入為 C棕孙,那么對 C\D\e() 的調(diào)用就會被轉(zhuǎn)換為 A\B\C\D\e()舔亭。
3、在命名空間內(nèi)部蟀俊,所有的沒有根據(jù)導(dǎo)入規(guī)則轉(zhuǎn)換的限定名稱均會在其前面加上當(dāng)前的命名空間名稱钦铺。例如,在命名空間 A\B 內(nèi)部調(diào)用 C\D\e()肢预,則 C\D\e() 會被轉(zhuǎn)換為 A\B\C\D\e() 矛洞。
4、非限定類名根據(jù)當(dāng)前的導(dǎo)入規(guī)則在編譯時轉(zhuǎn)換(用全名代替短的導(dǎo)入名稱)。例如沼本,如果命名空間 A\B\C 導(dǎo)入為C噩峦,則 new C() 被轉(zhuǎn)換為 new A\B\C() 。
5抽兆、在命名空間內(nèi)部(例如A\B)识补,對非限定名稱的函數(shù)調(diào)用是在運(yùn)行時解析的。例如對函數(shù) foo() 的調(diào)用是這樣解析的:在當(dāng)前命名空間中查找名為 A\B\foo() 的函數(shù)嘗試查找并調(diào)用 全局(global) 空間中的函數(shù) foo()辫红。
6凭涂、在命名空間(例如A\B)內(nèi)部對非限定名稱或限定名稱類(非完全限定名稱)的調(diào)用是在運(yùn)行時解析的。下面是調(diào)用 new C() 及 new D\E() 的解析過程: new C()的解析:1贴妻、在當(dāng)前命名空間中查找A\B\C類切油。2、嘗試自動裝載類A\B\C名惩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澎胡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绢片,更是在濱河造成了極大的恐慌滤馍,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件底循,死亡現(xiàn)場離奇詭異巢株,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)熙涤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門阁苞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人祠挫,你說我怎么就攤上這事那槽。” “怎么了等舔?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵骚灸,是天一觀的道長。 經(jīng)常有香客問我慌植,道長甚牲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任蝶柿,我火速辦了婚禮丈钙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘交汤。我一直安慰自己雏赦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著星岗,像睡著了一般填大。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伍茄,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天栋盹,我揣著相機(jī)與錄音,去河邊找鬼敷矫。 笑死,一個胖子當(dāng)著我的面吹牛汉额,可吹牛的內(nèi)容都是我干的曹仗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蠕搜,長吁一口氣:“原來是場噩夢啊……” “哼怎茫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妓灌,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤轨蛤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虫埂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祥山,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年掉伏,在試婚紗的時候發(fā)現(xiàn)自己被綠了缝呕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡斧散,死狀恐怖供常,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸡捐,我是刑警寧澤栈暇,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站箍镜,受9級特大地震影響塘砸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喉刘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一膘茎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脚草,春花似錦赫悄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姑隅。三九已至,卻和暖如春倔撞,著一層夾襖步出監(jiān)牢的瞬間讲仰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工痪蝇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鄙陡,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓躏啰,卻偏偏與公主長得像趁矾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子给僵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 提出問題 解決問題--命名空間的使用 PHP的命名空間(namespace)是php5.3之后才有的毫捣。這個概念在C...
    洞房花豬閱讀 2,841評論 0 3
  • 一、 為什么需要命名空間(問題提出) 命名空間是ANSIC++引入的可以由用戶命名的作用域帝际,用來處理程序中 常見的...
    IvanRunning閱讀 2,359評論 0 2
  • http://php.net/manual/zh/language.namespaces.basics.php#l...
    JasonQiao閱讀 289評論 0 0
  • 對于命名空間蔓同,官方文檔已經(jīng)說得很詳細(xì)[查看],我在這里做了一下實(shí)踐和總結(jié)蹲诀。 命名空間一個最明確的目的就是解決重名問...
    斯文小螞蟻閱讀 378評論 0 0
  • 前進(jìn)道路是彎曲曲折斑粱,如果沒有能夠激勵自己一直前行的動力,很容易就迷失在前進(jìn)的道路上侧甫,或是停下前進(jìn)的腳步珊佣。 所以當(dāng)我...
    楓丹白露蘇眉魚閱讀 207評論 0 2