PHP 5.3新特性命名空間規則解析及進階功能

來源:互聯網
上載者:User

日前發布的PHP 5.3中,最重要的一個新特性就是命名空間的加入。本文介紹了PHP命名空間的一些術語,其解析規則,以及一些進階功能的應用,希望能夠協助讀者在項目中真正使用命名空間。

在這裡中我們介紹了PHP命名空間的用途和namespace關鍵字,在這篇文章中我們將介紹一下use命令的使用以及PHP如何解析命名空間的名字的。

為了便於對比,我定義了兩個幾乎一樣的代碼塊,只有命名空間的名字不同。

  1. < ?php
  2. // application library 1
  3. namespace App\Lib1;
  4. const MYCONST = 'App\Lib1\MYCONST';
  5. function MyFunction() {
  6. return __FUNCTION__;
  7. }
  8. class MyClass {
  9. static function WhoAmI() {
  10. eturn __METHOD__;
  11. }
  12. }
  13. ?>
lib2.php

  1. < ?php
  2. // application library 2
  3. namespace App\Lib2;
  4. const MYCONST = 'App\Lib2\MYCONST';
  5. function MyFunction() {
  6. return __FUNCTION__;
  7. }
  8. class MyClass {
  9. static function WhoAmI() {
  10. eturn __METHOD__;
  11. }
  12. }
  13. ?>

開始之前先要理解幾個PHP命名空間相關術語。

◆完全限定名稱(Fully-qualified name)

任何PHP代碼都可以引用完全限定名稱,它是一個以命名空間反斜線開頭的標識符,如\App\Lib1\MYCONST,\App\Lib2\MyFunction( )等。

完全限定名稱是沒有任何歧義的,開頭的反斜線和檔案路徑的作用有點類似,它表示“根”全域空間,如果我們在全域空間中實現了一個不同的MyFunction( ),可以使用\MyFunction( )從lib1.php或lib2.php調用它。

完全限定名稱對一次性函數調用或對象初始化非常有用,但當你產生了大量的調用時它們就沒有實用價值了,在下面的討論中我們將會看到,PHP提供了其它選項以解除我們為命名空間打字的煩惱。

◆限定名稱(Qualified name)

至少有一個命名空間分隔字元的標識符,如Lib1\MyFunction( )。

◆非限定名稱(Unqualified name)

沒有命名空間分隔字元的標識符,如MyFunction( )。

在相同的命名空間內工作

仔細思考下面的代碼:

myapp1.php

     
  1. < ?php
  2. namespace App\Lib1;
  3. require_once('lib1.php');
  4. require_once('lib2.php');
  5. header('Content-type: text/plain');
  6. echo MYCONST . "\n";
  7. echo MyFunction() . "\n";
  8. echo MyClass::WhoAmI() . "\n";
  9. ?>

即使我們同時包括了lib1.php和lib2.php,MYCONST,MyFunction和MyClass標識符只能在lib1.php中引用,這是因為myapp1.php的代碼在相同的App\Lib1命名空間內。

執行結果:

  1. App\Lib1\MYCONST
  2. App\Lib1\MyFunction
  3. App\Lib1\MyClass::WhoAmI

命名空間匯入

可以使用use操作符匯入命名空間,如:

myapp2.php

< ?php

  1. use App\Lib2;
  2. require_once('lib1.php');
  3. require_once('lib2.php');
  4. header('Content-type: text/plain');
  5. echo Lib2\MYCONST . "\n";
  6. echo Lib2\MyFunction() . "\n";
  7. echo Lib2\MyClass::WhoAmI() . "\n";
  8. ?>

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

執行結果:

  1. App\Lib2\MYCONST
  2. App\Lib2\MyFunction
  3. App\Lib2\MyClass::WhoAmI

命名空間別名

命名空間別名可能是最有用的構想了,別名允許我們使用較短的名稱引用很長的命名空間。

myapp3.php

  1. < ?php
  2. use App\Lib1 as L;
  3. use App\Lib2\MyClass as Obj;
  4. header('Content-type: text/plain');
  5. require_once('lib1.php');
  6. require_once('lib2.php');
  7. echo L\MYCONST . "\n";
  8. echo L\MyFunction() . "\n";
  9. echo L\MyClass::WhoAmI() . "\n";
  10. echo Obj::WhoAmI() . "\n";
  11. ?>

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

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

執行結果:

  1. App\Lib1\MYCONST
  2. App\Lib1\MyFunction
  3. App\Lib1\MyClass::WhoAmI
  4. App\Lib2\MyClass::WhoAmI

PHP命名解析規則

PHP標識符名稱使用下列命名空間規則進行解析,請參考PHP使用者手冊瞭解更詳細的資訊:

1.在編譯時間調用完全限定函數、類或常量;

2.非限定名稱和限定名稱根據匯入規則進行翻譯,例如,如果A\B\C匯入為C,調用C\D\e( )就會被翻譯成A\B\C\D\e( );

3.在PHP命名空間內,所有限定名稱尚未根據匯入規則轉換,例如,如果在命名空間A\B中調用C\D\e( ),那麼會被翻譯成A\B\C\D\e( );

4.非限定類名稱根據當前的匯入規則進行轉換,使用全名替換匯入的簡短名稱,例如,如果類C在命名空間A\B中被匯入為X,那麼new X( )就會被翻譯為new A\B\C( );

5.在命名空間中非限定函數調用在運行時解析,例如,如果MyFunction( )在命名空間A\B中被調用,PHP首先會尋找函數\A\B\MyFunction( ),如果沒有找到,然後會在全域空間中尋找\MyFunction( );

6.調用非限定或限定類名在運行時被解析,例如,如果我們在命名空間A\B中調用new C( ),PHP將會尋找類A\B\C,如果沒有找到,PHP會嘗試自動載入A\B\C。

PHP命名空間進階特性

接下來讓我們看一看PHP命名空間的一些進階特性。

__NAMESPACE__常量

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

     
  1. < ?php
  2. namespace App\Lib1;
  3. echo __NAMESPACE__; // outputs: App\Lib1
  4. ?>

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

     
  1. < ?php
  2. namespace App\Lib1;
  3. class MyClass {
  4. public function WhoAmI() {
  5. return __METHOD__;
  6. }
  7. }
  8. $c = __NAMESPACE__ . '\\MyClass';
  9. $m = new $c;
  10. echo $m->WhoAmI(); // outputs: App\Lib1\MyClass::WhoAmI
  11. ?>

namespace關鍵字

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

     
  1. < ?php
  2. namespace App\Lib1;
  3. class MyClass {
  4. public function WhoAmI() {
  5. return __METHOD__;
  6. }
  7. }
  8. $m = new namespace\MyClass;
  9. echo $m->WhoAmI(); // outputs: App\Lib1\MyClass::WhoAmI
  10. ?>

自動載入命名空間類

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

     
  1. < ?php
  2. $obj= new MyClass1(); // classes/MyClass1.php is auto-loaded
  3. $obj= new MyClass2(); // classes/MyClass2.php is auto-loaded
  4. // autoload function
  5. function __autoload($class_name) {
  6. require_once("classes/$class_name.php");
  7. }
  8. ?>

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

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

/classes/App/Lib1/MyClass.php

     
  1. < ?php
  2. namespace App\Lib1;
  3. class MyClass {
  4. public function WhoAmI() {
  5. return __METHOD__;
  6. }
  7. }
  8. ?>

在根資料夾下的檔案就使用下面的代碼了:

myapp.php

     
  1. < ?php
  2. use App\Lib1\MyClass as MC;
  3. $obj = new MC();
  4. echo $obj->WhoAmI();
  5. // autoload function
  6. function __autoload($class) {
  7. // convert namespace to full file path
  8. $class = 'classes/' . str_replace('\\', '/', $class) . '.php';
  9. require_once($class);
  10. }
  11. ?>

解釋:

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

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

3.字串App\Lib1\MyClass被傳遞給__autoload函數,使用檔案路徑正斜線替換所有命名空間中的反斜線,然後修改字串,classes\App\Lib1\MyClass.php檔案被自動載入;

總結

有關PHP命名空間的使用就介紹到這裡,希望您能夠對PHP的命名空間有一個新的認識,並希望你能在新項目中真正使用命名空間。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.