本文移到:http://www.phpgay.com/Article/detail/classid/2/id/53.htmlphp
1.命名空間的語法:html
<?phpthinkphp
namespace 名稱;session
?>函數
例子:<?phpspa
namespace blog; code
?>htm
注意:在namespace以前不能有任何輸出,就像session_start同樣,同一個php文件中能夠多個命名空間。blog
<?php文檔
namespace blog;
class manage{}
namespace message;
class manage{};
$msge = new manage();
$blog_msge = new \blog\manage();
?>
上面的例子定義了兩個命名空間,兩個命名空間裏面都定義了相同名稱的manage類,當第一個new manage的時候實例的是緊接着的定義的命名空間裏面的類。當要調用其餘命名空間的類的時候就得用在前面加上命名空間的名稱,如\blog\manage這個就是調用blog空間裏面的manage類。
使用命名空間:若是調用的是當前命名空間裏面的元素,就直接元素名就能夠了,否則就得用:\空間名\元素名 這種形式來調用其餘命名空間的元素。
2.子空間,子命名
<?php
namespace blog\log;
class data{}
namespace blog\message;
class data{}
?>
這裏就應用到了子空間,都是blog命名空間下面的模塊,log命名空間,message命名空間。子空間還能夠定義多層
3.公共命名空間
在一個命名空間裏引入一個腳本,腳本里的元素不會歸屬到這個命名空間。若是這個腳本里沒有定義其它命名空間,它的元素就始終處於公共空間中:
調用公共空間的方式是直接在元素名稱前加 \ 就能夠了,不然PHP解析器會認爲我想調用當前空間下的元素。除了自定義的元素,還包括PHP自帶的元素,都屬於公共空間。
要提一下,其實公共空間的函數和常量不用加 \ 也能夠正常調用(不明白PHP爲何要這樣作),可是爲了正確區分元素,仍是建議調用函數的時候加上 \
<?php
namespace thinkphp;
include "function.php"; //裏面的元素是公共空間
$fun = new function();//錯誤調用
$fun = new \function(); //正確的調用
?>
4.名稱術語
在說別名和導入以前,須要知道關於空間三種名稱的術語,以及PHP是怎樣解析它們的。官方文檔說得很是好,我就直接拿來套了。
1.非限定名稱,或不包含前綴的類名稱,例如 $comment = new Comment();。若是當前命名空間是Blog\Article,Comment將被解析爲Blog\Article\Comment。若是使用 Comment的代碼不包含在任何命名空間中的代碼(全局空間中),則Comment會被解析爲Comment。
2.限定名稱,或包含前 綴的名稱,例如 $comment = new Article\Comment();。若是當前的命名空間是Blog,則Comment會被解析爲Blog\Article\Comment。若是使用 Comment的代碼不包含在任何命名空間中的代碼(全局空間中),則Comment會被解析爲Comment。
3.徹底限定名稱,或包含了全局前綴操做符的名稱,例如 $comment = new \Article\Comment();。在這種狀況下,Comment老是被解析爲代碼中的文字名(literal name)Article\Comment。
其實能夠把這三種名稱類比爲文件名(例如 comment.php)、相對路徑名(例如 ./article/comment.php)、絕對路徑名(例如 /blog/article/comment.php),這樣可能會更容易理解。
例子:
<?php
namespace blog;
class comment{}
$com = new comment();表示非限定名稱,只在當前命名空間有效。這個會被解析成blog\comment
$com = new article\comment():表示限定名稱,相對於blog空間,會被解析成blog\article\comment
$com = new \blog\article\comment():表示徹底限定,在blog前面有\,這個會被解析成\blog\article\comment
?>
4.別名和導入
別名和導入能夠看做是調用命名空間元素的一種快捷方式。PHP並不支持導入函數或常量。
導入:use blog
別名:use blog as bg
<?php
namespace blog;
class comment{}
namesapce bbs;
use blog;
$com = new blog\comment();
use blog\comment;
$com = new comment();
use blog\comment as bgcom;
$com = new bgcom();
?>
注意:若是導入一個命名空間的,命名空間的元素與當前空間有相同的名字元素將會發生致命錯誤。
<?php
namespace Blog\Article;
class Comment { }
namespace BBS;
class Comment { }
Class Comt { }
//導入一個類
use Blog\Article\Comment;
$article_comment = new Comment(); //與當前空間的Comment發生衝突,程序產生致命錯誤
//爲類使用別名
use Blog\Article\Comment as Comt;
$article_comment = new Comt(); //與當前空間的Comt發生衝突,程序產生致命錯誤
?>
5.命名空間的動態調用
PHP提供了namespace關鍵字和__NAMESPACE__魔法常量動態的訪問元素,__NAMESPACE__能夠經過組合字符串的形式來動態訪問:
namespace:表示當前的命名空間
__NAMESPACE__:表示當前空間的名稱,字符串
<?php
namespace blog;
class comment();
$com = new namespace\comment();
$namespace_name = __NAMESPACE__.'\comment';
$com = new $namespace_name();
?>
字符串形式調用問題
上面的動態調用的例子中,咱們看到了字符串形式的動態調用方式,若是要使用這種方式要注意兩個問題。
1. 使用雙引號的時候特殊字符可能被轉義
namespace Blog\Article;
class name { }
//我是想調用Blog\Article\name
$class_name = __NAMESPACE__ . "\name"; //可是\n將被轉義爲換行符
$name = new $class_name(); //發生致命錯誤
?>
2. 不會認爲是限定名稱
PHP在編譯腳本的時候就肯定了元素所在的空間,以及導入的狀況。而在解析腳本時字符串形式調用只能認爲是非限定名稱和徹底限定名稱,而永遠不多是限定名稱。
namespace Blog;
//導入Common類
use Blog\Article\Common;
//我想使用非限定名稱調用Blog\Article\Common
$common_class_name = 'Common';
//實際會被看成非限定名稱,也就表示當前空間的Common類,但我當前類沒有建立Common類
$common = new $common_class_name(); //發生致命錯誤:Common類不存在
//我想使用限定名稱調用Blog\Article\Common
$common_class_name = 'Article\Common';
//實際會被看成徹底限定名稱,也就表示Article空間下的Common類,但我下面只定義了Blog\Article空間而不是Article空間
$common = new $common_class_name(); //發生致命錯誤:Article\Common類不存在
namespace Blog\Article;
class Common { }
?>