這篇文章主要介紹了php命名空間的相關問題和技巧,需要的朋友可以參考下
1、什麼是命名空間? 命名空間是一種特殊的作用域,它包含處於該作用域下的標識符,同時它本身也是一種標識符。可以把命名空間與操作系統的目錄對應起來。一個命名空間相當於一個目錄,命名空間裡的類,函數,常量,相當於目錄裡的文件。同一個目錄(命名空間)裡的文件名不能相同,但是不同的目錄裡可以有相同名字的文件。 2、使用命名空間為了解決什麼問題? 解決名字沖突,比如定義了一個類,正好這個類與PHP內部的類或是include進來的一個類庫裡的類重名了。 提高代碼可讀性,命名空間有一個別名功能,它可以幫你給一個長達十幾個字符的類名起一個別名,從而縮短代碼,也不用擔心與其他空間的命名沖突。 3、哪一些代碼會受命名空間的影響。 三類:類、函數、常量。只有它們兄弟三受影響,其他的該干嘛,還干嘛去。說到常量,php 5.3以後可以使用const關鍵字來定義常量,5.3這前使用define,命名空間只對const關鍵字有效。 4、命名空間如何定義 代碼如下: namespace MyProject; const CONNECT_OK = 1;//php5.3以後 class Connection { /* ... */ } function connect() { /* ... */ } #例子二 namespace MyProjectSubLevel; const CONNECT_OK = 1;//php5.3以後 class Connection { /* ... */ } function connect() { /* ... */ } 使用 `namespace 空間名` 來申明一個空間,在namespace之前除了declare語句不能有任何其他php語句,同時也不能有任何非php代碼,連空格都不能有。 以下為錯誤的形式: 代碼如下: $a = 1; namespace MyProject; ?>www.jb51.net //Fatal error: Namespace declaration statement has to be the very first statement in the script... 另外同一個命名空間是可以定義在多個文件中,這對於組織框架是非常有用的。即以同一個namespace MyProject;開頭的文件,它們是同一個命名空間。所以注意文件之間可不要有相同的類/函數/常量名哦。 當然同一個文件也可以定義多個命名空間,不過非常不建議這樣做的。(了解同一個文件定義多個命名空間) 5、命名空間如何使用 命名空間有三種使用形式: . 非限定名稱 -- 沒有使用任何的分割符,直接使用類/函數/常量名,如:new Foo(); foo(); echo FOO; 當文件有使用命名空間時, 代碼如下: <?php namespace MyObject; new Foo(); // 調用MyObjectFoo(); foo(); //調用MyObjectFoo(); echo FOO; //調用MyObjectFOO; 非完全限定名稱 -- 不是以分割符開頭,如 new SubFoo(); 這種形式與非限定名稱方式一樣。 復制代碼 代碼如下: <?php namespace MyObject; new SubFoo(); //調用MyObjectSubFoo(); 完全限定名稱 -- 以分割符開頭的方式,相當於操作系統裡的絕對地址。如 new OtherNSFoo(); 代碼如下: <?php namespace MyObject; new OtherNSFoo(); //調用OtherNsFoo(); 不管MyObject命名空間。 Tip: 對於函數和常量,還有一個特殊的地方(後備全局函數/常量)。 代碼如下: <?php namespace MyObject; funcname(); //如果MyObjectFuncname存在則調用MyObjectFuncname(),否則試著調用funcname(); echo FOO; //同上。 對於類,也有一個特殊的地方。 代碼如下: <?php namespace MyObject; new Foo(); //*如果MyObjectFoo存在,調用之,如果不存在,調用__autoload試著加載MyObjectFoo類進來。 //注意對於類是不會去自動去調用全局作用域下的類的。 之前說了,命名空間還有一個用途-取別名。 代碼如下: namespace MyObject; use OtherNSSub as Other; use OtherNSSub2; //相當於use OtherNSSub2 as Sub2; use /MyClass; new Foo(); //調用MyObjectFoo(); new OtherFoo(); //調用 OtherNSSubFoo(); new Sub2Foo(); //調用OtherNSSub2Foo(); new MyClass(); //調用MyClass(); 6、動態命名空間 動態總是能讓人摸不著頭腦,然而又帶來靈活性。命名空間同樣可以使用動態語言特點,但要注意由於直接調用命名空間是編譯時解析的,而動態特征並非編譯時解析。所以一定要加前綴。如: 代碼如下: namespace MyObjectSub; new Foo(); //調用 MyObjectSubFoo(), 編譯時已經解析成MyObjectSubFoo $a = 'Foo'; new $a(); //調用的是Foo(),而不是MyObjectSubFoo() $b = 'MyObjectSubFoo'; //等價於 MyObjectSubFoo new $b(); //調用MyObjectSubFoo() //如果使用雙引號,要用,如 $a = "MyObjectSub"; 附1:同一個文件定義多個命名空間 方法有兩種: 代碼如下: namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } 方法一,記流水帳。 代碼如下: namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { //全局 const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } 方法二,使用大括號把同一個命名空間的代碼放在大括號裡。這種方法,要求在大括號外不能有任何除了declare之外的代碼。對於全局作用域的代碼使用沒有空間名的大括號包圍起來