PHP新特性命名空間的詳解介紹

來源:互聯網
上載者:User

1、什麼是命名空間

如果你只需要知道現代PHP特性中的一個,那就應該是命名空間。命名空間在PHP5.3.0中引入,其作用是按照一種虛擬階層組織PHP代碼,這種階層類似作業系統中檔案系統的目錄結構。命名空間是現代PHP組件生態的基礎,現代的PHP組件架構代碼都是放在各自全域唯一的廠商命名空間中,以免和其他廠商使用的常見類名衝突。

下面我來看看真實的PHP組件是如何使用命名空間的。Laravel架構中的Http組件用於管理HTTP請求和響應,這個組件用到了常見的類名,例如Request、Response,很多其他PHP組件也用到了這樣的類名,既然其他PHP代碼也用到了相同的類名,那怎麼使用這個組件呢?其實我們可以放心使用,因為這個組件的代碼放在了唯一的廠商命名空間Illuminate中。開啟這個組件在GitHub中的倉庫(https://github.com/laravel/framework/blob/master/src/Illuminate/Http/Response.php),找到Response.php檔案:

第3行代碼如下:

namespace Illuminate\Http;
這一行是PHP命名空間聲明語句,聲明命名空間的代碼始終應該放在<?php標籤後的第一行。通過這個命名空間的聲明語句我們可以看到Response位於廠商命名空間Illuminate中(最頂層命名空間),我們還看到Response類在子命名空間Http中,你可以看下和Response.php檔案在同一層級的其他檔案,會發現它們都使用相同的命名空間聲明語句。

命名空間的作用是封裝和組織相關的PHP類,就像在檔案系統中把相關的檔案放在同一個目錄中一樣。PHP命名空間和作業系統的物理檔案系統不同,這是一個虛擬概念,沒必要和檔案系統中的目錄結構完全相同,雖然如此,但是大多數PHP組件為了相容廣泛使用的PSR-4自動載入標準,會把命名空間放到對應檔案系統的子目錄中。

2、為什麼使用命名空間
前面已經提到過,我們的代碼可能和其他開發人員的代碼使用相同的類名、介面名、函數或常量名,如果不使用命名空間,名稱會起衝突,導致PHP執行出錯。而使用命名空間將代碼放到唯一的廠商命名空間,我們的代碼就可以和其他開發人員使用相同的類名、介面名、函數或常量名。

當然如果你開發的是小型個人項目,只有少量的依賴,類名衝突可能不是問題,但是如果在團隊中工作,開發用到許多第三方依賴的大型項目,就要認真對待命名衝突問題,因為你無法控制項目依賴在全域命名空間中引入的類、介面、函數和常量,這也是為什麼要使用命名空間的原因。

3、聲明命名空間
每個PHP類、介面、函數和常量都在命名空間中,聲明命名空間很簡單,在<?php標籤後的第一行聲明,聲明語句以namespace開頭,隨後是一個空格,然後是命名空間的名稱,最後以;結尾。

命名空間經常用於設定頂層廠商名,比如我們設定廠商名為LaravelAcademy:

<?php
namespace LaravelAcademy;
在這個命名空間聲明語句後聲明的所有PHP類、介面、函數和常量都在LaravelAcademy命名空間中,而且和Laravel學院有某種關係。如果我們想組織學院用到的代碼該怎麼做呢?答案是使用子命名空間。

子命名空間的聲明方式和前面的樣本完全一樣,唯一的區別是我們要使用\符號把命名空間和子命名空間分開,例如:

<?php
namespace LaravelAcademy\ModernPHP;
這個命名空間後的所有類、介面、函數和常量都位於LaravelAcademy\ModernPHP中。

在同一個命名空間中的類沒必要在同一個PHP檔案中聲明,可以在PHP檔案的頂部指定一個命名空間或子命名空間,此時,這個檔案的代碼就是該命名空間或子命名空間的一部分。因此我們可以在不同檔案中編寫屬於同一個命名空間的多個類。

註:廠商命名空間是最頂層的命名空間,也是最重要的命名空間,用於識別品牌或組織,必須具有全域唯一性。子命名空間相對而言沒那麼重要,但是可以用於組織項目的代碼。
4、匯入和別名
在命名空間出現之前,PHP開發人員使用Zend風格的類名解決命名衝突問題,這是一種類的命名方案,因Zend架構而流行,這種命名方案在PHP類名中使用底線的方式表示檔案系統的目錄分隔字元。這種約定有兩個作用:其一,確保類名是唯一的;其二,原生的自動載入器會把類名中的底線替換成檔案系統的目錄分隔字元,從而確定檔案的路徑。例如,Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query類對應的檔案是Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php。可以看出,這種命名有個缺點:類名特別長。

現代的PHP命名空間也有這個問題,例如上述Response類完整的全名是Illuminate\Http\Response,幸好,我們可以通過匯入以及建立別名的方式來改變這一狀況。

匯入的意思是指,在每個PHP檔案中告訴PHP想使用哪個命名空間、類、介面、函數和常量,匯入後就不用使用全名了:

<?php
use Illuminate\Http\Response;

$response = new Response(‘Oops’, 400);
$response->send();
我們通過use關鍵字告訴PHP,我們想使用Illuminate\Http\Response類,我們只需要輸入一次完整類名,隨後執行個體化Response的時候,無需使用完整的類名。

如果覺得這樣的類名還是長,可以建立別名。建立別名指的是告訴PHP我要使用簡單的名稱引用匯入的類、介面、函數或常量:

<?php

use Illuminate\Http\Response as Res;

$res = new Res(‘Oops’, 400);
$res->send();
從PHP 5.6開始還可以匯入函數和常量,不過要調整use關鍵字的句法,如果要匯入函數,需要使用use func:

<?php
use func Namespace\functionName

functionName();
如果想匯入常量,可以使用use constant:

<?php
use constant Namespace\CONST_NAME;

echo CONST_NAME;
當然也支援別名,建立方式和類一樣。

5、實用技巧
多重匯入

如果想要在PHP檔案中匯入多個類、介面、函數或常量,需要在PHP檔案的頂部使用多個use語句,PHP支援用簡短的文法把多個use語句寫成一行:

<?php
use Illuminate\Http\Request,
Illuminate\Http\Response;
但是為了可讀性,建議不要這麼寫,還是一行寫一個use語句比較好:

<?php
use Illuminate\Http\Request;
use Illuminate\Http\Response;
一個檔案使用多個命名空間

PHP允許在一個檔案中定義多個命名空間:

<?php
namespace Foo {
    //聲明類、介面、函數、常量
}

namespace Bar {
    //聲明類、介面、函數、常量
}
但這麼做不好,違背了“一個檔案一個類”的良好實踐,因此不建議這麼做。

全域命名空間

如果引用的類、介面、函數和常量沒有指定命名空間,PHP假定引用的類、介面、函數和常量在當前的命名空間中。如果要使用其他命名空間的類、介面、函數或常量,需要使用完整PHP類名(命名空間+類名)。

有些代碼在全域命名空間中,沒有命名空間,比如原生的Exception類就是這樣。在命名空間中引用全域的代碼時,需要在類、介面、函數或常量前加\符號:

<?php
namespace My\App;

class Foo {
    public function doSomething() {
        throw new \Exception();
    }
}
自動載入

命名空間還為PHP-FIG制定的PSR-4自動載入標準奠定了堅實的基礎,大多數現代的PHP組件都使用了這種自動載入模式,使用依賴管理器Composer可以自動附加元件目的依賴,後續我們還會詳細介紹Composer和PHP-FIG,現在你只需要知道沒有命名空間,就沒有現代的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.