ThinkPHP是一個快速、相容且簡單的輕量國產PHP開發架構,使用ThinkPHP框架可以大幅簡化我們的開發過程,節省時間。這篇文章就是php中文網帶一個大家學習ThinkPHP中十分重要的概念:命名空間。
ThinkPHP採用命名空間方式定義和自動載入類別庫文件,有效的解決了多模組和Composer類別庫之間的命名空間衝突問題,並且實作了更有效率的類別庫自動載入機制。
可以移步至我們php中文網課程:彈指間學會PHP程式之命名空間教學
我們php中文網也提供了相關影片課程:獨孤九賤(5)_ThinkPHP5影片教學
由於PHP語法「裡不支援函數重載機制,如果一個應用程式裡有兩個同名的方法,怎麼辦?在Yii框架為了避免名字重複造成問題,全部的類前邊都有 C 字樣,而在ThinkPHP裡就引入了命名空間這個概念。其中有幾點需要特別注意:
a) 命名空間是虛擬的定義空間,不是真實存在目錄
b) 命名空間的分隔符號都是反斜線\
c) 命名空間只對函數,類,常數(const定義的常數,非define定義的常數)有效。
d) 命名空間有三種存取方式:非限定名稱存取方式;限定名稱存取方式;完全限定名稱存取方式。
接下來就一一詳細說明。
一、命名空間只對函數,類,常數(const定義的常數,非define定義的常數)有效。
# 這裡我們宣告了兩個命名空間space1和space2 ,兩個命名空間下面有同名的函數getmsg(),同名的常數a,同名的類別Animal,因為它們處於不同的命名空間下,所以不會產生錯誤。我們在瀏覽器中打開,得到如下輸出:helloworld。
如果我們試著用define定義兩個同名常數呢?
瀏覽器中開啟封包如下錯誤:
所以命名空間只對函數,類,常數(const定義的常數,非define定義的常數)有效。
# 上面宣告的命名空間space1和space2都是單級命名空間,形狀如space1\space2\space3的命名空間為多層命名空間,分隔符號為\。以下介紹三種命名空間存取方式:
當以非限定名稱存取方式存取時,存取的是目前命名空間下的函數(類別和常數同理),所以以上程式碼輸出結果是:world。
若想要在name2\space2 命名空間下存取name1\space1下的getmsg()方法,可以使用完全限定名稱存取方式(相當於絕對路徑存取)。
所以上述程式碼的輸出結果為:hello。
# 限定名稱存取方式與完全限定名稱存取方式差異只在最前面的\ 。如果上例使用限定名稱存取方式訪問,則將最後一行改為:name1\space1\getmsg();
此時,我們在瀏覽器中打開,發現如下錯誤:
提示我們無法找到命名空間name2\space2\name1\space1 下的getmsg() 函數。原因是限定名稱訪問方式相當於相對路徑訪問,我們在當前命名空間下使用限定名稱訪問方式訪問:name1\space1\getmsg(),會在當前命名空間下尋找name1\space1下的getmsg()函數,找不到就會報錯。所以,如果我們再宣告一個名為: name2\space2\name1\space1 的命名空間,上述存取可以正常執行,如下:
輸出結果是:hello -world。
# 透過上面的例子,我們可以看到如果想要在當前命名空間下使用另一個命名空間下的函數、常數或類別元素的時候,我們需要使用完全限定訪問方式進行訪問,寫程式碼比較繁瑣,所以,我們可以引入命名空間,然後使用限定名稱訪問方式進行訪問,簡化訪問過程。
輸出結果為:hello dog
與命名空間的引入方式類似,使用use 關鍵字引入空間類別元素,然後直接使用非限定存取方式進行參觀即可。不過,在目前命名空間下不能存在與引入類別同名的類,否則會產生錯誤。
#輸出結果為:dog大黃。
若我們沒有使用namespace 關鍵字宣告命名空間,則其屬於公共空間。
這裡我們建立兩個php文件,1.php 和2.php,1.php命名空間為name1\space1, 2.php為公共空間。
1.php:
namespace name1\space1; header("content-type:text/html;charset=utf-8"); class Animal { public $obj = 'dog'; static $name = '大黄'; } function getmsg() { echo 'hello'; } const MN = 123; //在命名空间中引入公共命名空间 include ('./2.php'); getmsg(); //访问的是当前空间下的getmsg()函数 echo '</br>'; \getmsg(); //访问的是公共命名空间(即2.php文件)下的getmsg()函数 echo '</br>'; echo MN; //会先在当前命名空间下寻找MN常量,如果找到就输出,如果找不到,就会去公共命名空间寻找MN常量 echo '</br>'; echo \MN; //访问的是公共命名空间(即2.php文件)下的MN常量
#2.php:
//没有指定命名空间,则其属于公共命名空间 function getmsg() { echo 'world'; } const MN = '456';
瀏覽器中開啟1.php ,輸出結果為:
hello
world
123
456
在thinkphp5.0中,命名空間是虛擬的定義空間,不是真實存在目錄。只不過是官方在宣告命名空間時,命名空間的名稱刻意與目錄結構有對應關係。
例如,我們開啟application/index/controller 資料夾下的Index.php 文件,其命名空間為: app\index\controller。在目錄結構中並不存在。
命名空間別名
框架允許為命名空間定義別名,例如:
namespace app\index\model; use think\Model; class User extends Model { }
原來在控制器裡面呼叫方式為:
namespace app\index\controller; use app\index\model\User; class Index { public function index() { $user = new User(); } }
如果我們在應用公共檔案中註冊命名空間別名如下:
\think\Loader::addNamespaceAlias('model','app\index\model');
那麼,上面的控制器程式碼就可以更改為:
namespace app\index\controller; use model\User; class Index { public function index() { $user = new User(); } }
相关资料推荐: