2-1-1-命名空間

一、(創建)聲明一個命名空間

子空間: 命名空間的調用語法像文件路徑一樣是有道理的,它允許我們自定義子空間來描述各個空間之間的關係。
公共空間:在一個命名空間裏引入一腳本,腳本里的元素不會歸屬到這個命名空間。如果這個腳本里沒有定義其它命名空間,它的元素就始終處於公共空間中
二、引用一個命名空間
要以當前空間爲基點。

三、別名和導入
空間的三種名稱;1.非限定名稱  2.限定名稱  3.完全限定名稱
其實可以把這三種名稱類比爲文件名(例如 comment.php)、相對路徑名(例如 ./article/comment.php)、絕對路徑名(例如 /blog/article/comment.php)

三、示例


<?php
//創建空間Blog,當前腳本文件的第一個命名空間前面不能有任何代碼
namespace Blog;

class Comment { }

//非限定名稱,表示當前Blog空間
//這個調用將被解析成 Blog\Comment();
$blog_comment = new Comment();//函數和常量的用法跟類是一樣的

//限定名稱,表示相對於Blog空間
//這個調用將被解析成 Blog\Article\Comment();
$article_comment = new Article\Comment(); //類前面沒有反斜杆\

//完全限定名稱,表示絕對於Blog空間
//這個調用將被解析成 Blog\Comment();
$article_comment = new \Blog\Comment(); //類前面有反斜杆\

//完全限定名稱,表示絕對於Blog空間
//這個調用將被解析成 Blog\Article\Comment();
$article_comment = new \Blog\Article\Comment(); //類前面有反斜杆\


//創建Blog的子空間Article
namespace Blog\Article;

class Comment { }
?>



<?php
namespace Blog\Article;

class Comment { }

//創建一個BBS空間(我有打算開個論壇)
namespace BBS;

//導入一個命名空間
use Blog\Article;
//導入命名空間後可使用限定名稱調用元素
$article_comment = new Article\Comment();

//爲命名空間使用別名
use Blog\Article as Arte;
//使用別名代替空間名
$article_comment = new Arte\Comment();

//導入一個類
use Blog\Article\Comment;
//導入類後可使用非限定名稱調用元素
$article_comment = new Comment();

//爲類使用別名
use Blog\Article\Comment as Comt;
//使用別名代替空間名
$article_comment = new Comt();

?>

其他例子:

文件之間的關係和命名空間之間的關係
//lib1.php

    < ?php  
    // application library 1  
    namespace App\Lib1;  
    const MYCONST = 'App\Lib1\MYCONST';  
    function MyFunction() {  
     return __FUNCTION__;  
    }  
    class MyClass {  
     static function WhoAmI() {  
    eturn __METHOD__;  
     }  
    }  
    ?>
    

//lib2.php

    < ?php  
    // application library 2  
    namespace App\Lib2;  
    
    const MYCONST = 'App\Lib2\MYCONST';  
    
    function MyFunction() {  
     return __FUNCTION__;  
    }  
    
    class MyClass {  
     static function WhoAmI() {  
     eturn __METHOD__;  
    }  
    }       

//在相同的命名空間內工作
/*即使我們同時包括了lib1.php和lib2.php,MYCONST,MyFunction和MyClass標識符只能在lib1.php中引用,這是因爲myapp1.php的代碼在相同的App\Lib1命名空間內。*/
//myapp1.php
    < ?php  
    namespace App\Lib1;  
    
    require_once('lib1.php');  
    require_once('lib2.php');  
    
    header('Content-type: text/plain');  
    echo MYCONST . "\n";  
    echo MyFunction() . "\n";  
    echo MyClass::WhoAmI() . "\n";  
    ?>

/*執行結果:

    App\Lib1\MYCONST  
    App\Lib1\MyFunction  
    App\Lib1\MyClass::WhoAmI  
*/


//命名空間導入
/*可以使用use操作符導入命名空間,如:*/
//myapp2.php

    < ?php  
    use App\Lib2;    
    require_once('lib1.php');  
    require_once('lib2.php');  
     
    header('Content-type: text/plain');  
    echo Lib2\MYCONST . "\n";  
    echo Lib2\MyFunction() . "\n";  
    echo Lib2\MyClass::WhoAmI() . "\n";  
    ?>  

可以定義任意數量的use語句,或使用逗號分隔成獨立的命名空間,在這個例子中我們導入了App\Lib2命名空間,但我們仍然不能直接引用 MYCONST,MyFunction和MyClass,因爲我們的代碼還在全局空間中,但如果我們添加了“Lib2\”前綴,它們就變成限定名稱 了,PHP將會搜索導入的命名空間,直到找到匹配項。

執行結果:    
    App\Lib2\MYCONST  
    App\Lib2\MyFunction  
    App\Lib2\MyClass::WhoAmI

命名空間別名:
別名允許我們使用較短的名稱引用很長的命名空間。

myapp3.php

    < ?php  
    use App\Lib1 as L;  
    use App\Lib2\MyClass as Obj;  
     
    header('Content-type: text/plain');  
    require_once('lib1.php');  
    require_once('lib2.php');  
     
    echo L\MYCONST . "\n";  
    echo L\MyFunction() . "\n";  
    echo L\MyClass::WhoAmI() . "\n";  
    echo Obj::WhoAmI() . "\n";  
    ?>  

第一個use語句將App\Lib1定義爲“L”,任何使用“L”的限定名稱在編譯時都會被翻譯成“App\Lib1”,因此我們就可以引用L\MYCONST和L\MyFunction而不是完全限定名稱了。

第二個use語句定義了“obj”作爲App\Lib2\命名空間中MyClass類的別名,這種方式只適合於類,不能用於常量和函數,現在我們就可以使用new Obj( )或象上面那樣運行靜態方法了。

執行結果:

    App\Lib1\MYCONST  
    App\Lib1\MyFunction  
    App\Lib1\MyClass::WhoAmI  
    App\Lib2\MyClass::WhoAmI  


    注:namespace 就是創建或者聲明一個空間,即將代碼置於何處。
    use用於對空間的導入,它的使用表示空間的相對關係。
    
    

__NAMESPACE__常量:


__NAMESPACE__是一個PHP字符串,它總是返回當前命名空間的名稱,在全局空間中它是一個空字符串。

    < ?php  
    namespace App\Lib1;  
    echo __NAMESPACE__; // outputs: App\Lib1  
    ?>  

    這個值在調試時非常有用,它也可由於動態生成一個完全限定類名,如:

    < ?php  
    namespace App\Lib1;  
     
    class MyClass {  
     public function WhoAmI() {  
    return __METHOD__;  
     }  
    }  
     
    $c = __NAMESPACE__ . '\\MyClass';  
    $m = new $c;  
    echo $m->WhoAmI(); // outputs: App\Lib1\MyClass::WhoAmI  
    ?>      
    

namespace關鍵字

    namespace關鍵字可以用於明確引用一個當前命名空間或子命名空間中的項目,它等價於類中的self命名空間:

    < ?php  
    namespace App\Lib1;  
     
    class MyClass {  
     public function WhoAmI() {  
    return __METHOD__;  
     }  
    }  
     
    $m = new namespace\MyClass;  
    echo $m->WhoAmI(); // outputs: App\Lib1\MyClass::WhoAmI  
    ?>  




自動載入命名空間類(這一部分以後再看)

PHP 5中最省時省力的特性是自動載入,在全局(非命名空間)PHP代碼中,可以寫一個標準自動載入函數:

    < ?php  
    $obj= new MyClass1(); // classes/MyClass1.php is auto-loaded  
    $obj= new MyClass2(); // classes/MyClass2.php is auto-loaded  
     
    // autoload function  
    function __autoload($class_name) {  
     require_once("classes/$class_name.php");  
    }  
    ?>  

在PHP 5.3中,你可以創建一個命名空間類的實例,在這種情況下,完全限定命名空間和類名傳遞給__autoload函數,例如,$class_name的值可 能是App\Lib1\MyClass。你可以在相同的文件夾下放置所有的PHP類文件,從字符串中提取命名空間,但那樣會導致文件名衝突。

另外,你的類文件層次結構會按照命名空間的結構重新組織,例如,MyClass.php文件可以創建在/classes/App/Lib1文件夾下:

/classes/App/Lib1/MyClass.php

    < ?php  
    namespace App\Lib1;  
     
    class MyClass {  
     public function WhoAmI() {  
    return __METHOD__;  
     }  
    }  
    ?>  

在根文件夾下的文件就使用下面的代碼了:

myapp.php

    < ?php  
    use App\Lib1\MyClass as MC;  
     
    $obj = new MC();  
    echo $obj->WhoAmI();  
     
    // autoload function  
    function __autoload($class) {  
     // convert namespace to full file path  
     $class = 'classes/' . str_replace('\\', '/', $class) . '.php';  
     require_once($class);  
    }  
    ?>  

解釋:

1.類App\Lib1\MyClass的別名是MC;

2. new MC( )在編譯時被翻譯成new App\Lib1\MyClass( );

3.字符串App\Lib1\MyClass被傳遞給__autoload函數,使用文件路徑正斜線替換所有命名空間中的反斜線,然後修改字符串,classes\App\Lib1\MyClass.php文件被自動載入;   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章