[翻譯]如何使用PHP命名空間(二):匯入,別名和命名解析

來源:互聯網
上載者:User
原文地址:http://www.sitepoint.com/php-namespaces-import-alias-resolution/
本系列文章的第一部分討論了為什麼PHP命名空間是有益的及namespace關鍵字。本文將繼續研究use命令及PHP解析命名空間的方式。
在下面的樣本中,定義了兩段幾乎完全相同的代碼,唯一的不同之處就在於它們的命名空間。  lib1.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 return __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 return __METHOD__;
11 }
12 }
13 ?>

先來瞭解一些PHP術語:
完全限定名
任何PHP代碼都具有完全限定名——一個以反斜線起始的標識符。例如:\App\Lib1\MYCONST, \App\Lib2\MyFunction()。
完全限定名不會產生任何歧義。首個反斜線與檔案系統路徑類似,都指明了“根”全域空間。如果在全域空間內實現了一個MyFunction()函數,可在lib1.php和lib2.php中使用“\MyFunction()”對其進行調用。
完全限定名對一次性函數調用或對象初始化有協助。然而,它們不適用於大量調用的情況。就像接下來要看到的,PHP為命名空間輸入提供了其他一些選擇。
部分限定名
至少有一個命名空間分隔字元的標識符。例如:Lib1\MyFunction().
未限定名
沒有命名空間分隔字元的標識符。例如: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, and MyClass只會引用lib1.php中的代碼。因為myapp1.php的代碼同樣位於App\lib1命名空間內。
result:

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

命名空間匯入
命名空間可通過use操作符匯入。例如
myapp2.php

1 <?php
2 use App\Lib2;
3 require_once('lib1.php');
4 require_once('lib2.php');
5 header('Content-type: text/plain');
6 echo Lib2\MYCONST . "\n";
7 echo Lib2\MyFunction() . "\n";
8 echo Lib2\MyClass::WhoAmI() . "\n";
9 ?>
可使用任意數量的use語句或使用逗號分隔每個獨立的命名空間。在此例中,匯入了“App\Lib2”命名空間。但此刻仍然無法直接引用MYCONST, MyFunction 或 MyClass,因為調用他們的代碼位於全域空間內,PHP將會在全域空間內尋找它們。然而,如果我們加入“Lib2\”首碼,它們便形成部分限定名,PHP將會在已匯入的命名空間內搜尋直到找到匹配項。result
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()來建立執行個體或直接調用靜態方法了。 result:
1 App\Lib1\MYCONST
2 App\Lib1\MyFunction
3 App\Lib1\MyClass::WhoAmI
4 App\Lib2\MyClass::WhoAmI

PHP命名解析規則
PHP標識符命名解析遵循以下規則:
1. 在編譯階段解析擁有完全限定名的常量、類或函數的調用。
2. 未限定和部分限定名根據命名空間匯入規則進行解釋。例如,如果命名空間A\B\C被匯入且設定別名為C,那麼C\D\e()調用將被解釋為A\B\C\D\e()
3. 在命名空間內,所有未根據命名空間匯入規則進行解釋的部分限定名都會擁有當前命名空間的首碼。例如:如果在命名空間A\B內執行C\D\e()調用,它將會被解釋為 A\B\C\D\e()。4. 未限定的類名會根據當前置入的命名空間進行解釋,同時會使用全名來代替縮寫後的名稱。例如:如果在命名空間A\B內的類C被匯入為X,new X()將被解釋為 new A\B\C()。
5. 命名空間內的未限定函數調用會在運行時解析。例如:如果MyFunction()在命名空間A\B內被調用,PHP首先會搜尋函數\A\B\MyFunction(),如果未找到匹配項,PHP會在全域空間內搜尋\MyFunction()函數。
6. 調用未限定或部分限定名的類會在運行時解析。例如:如果在命名空間A\B內調用new C(),PHP會搜尋類A\B\C,如果未能找到匹配項,PHP將會試圖自動載入類A\B\C。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.