1. 程式人生 > >關於PHP名稱空間的討論

關於PHP名稱空間的討論

什麼是名稱空間?

    根據php.net官方翻譯文件描述,名稱空間是這樣定義的:

什麼是名稱空間?從廣義上來說,名稱空間是一種封裝事物的方法。

在PHP中,名稱空間用來解決在編寫類庫或應用程式時建立可重用的程式碼如類或函式時碰到的兩類問題:

(1)、使用者編寫的程式碼與PHP內部的類/函式/常量或第三方類/函式/常量之間的名字衝突。

(2)為很長的識別符號名稱(通常是為了緩解第一類問題而定義的)建立一個別名(或簡短)的名稱,提高原始碼的可讀性。

    這個描述太官方,不太好懂。

    簡單地說,這個名稱空間,就是用來解決定義的常量、函式和類,存在重名的問題,一是解決使用者定義的類/函式/常量與PHP內部的類/函式/常量同名的問題,二是解決不同軟體開發小組或不同軟體公司定義的類/函式/常量同名的問題,而你需要同時使用這兩個公司定義的類庫。

    比如,新冠肺炎防控期間,Ahcme學校開發了用於收集學生疫情報告的資訊的軟體平臺,AnHui省也開發了省級疫情監測平臺,用於彙總各高校疫情資訊進行大資料分析和預警。現在,由Wisedu公司來做這個對接開發,用於將ahcme學校的填報明細資料每天定時上傳到省級疫情平臺。

    在Wisedu公司開始做對接工作之前,Ahcme學校和Anhui省都已經基本完成了程式碼開發,他們有了下面的php程式碼檔案:

Achme學校的程式碼是 ahcme_sample.php檔案:

 

Anhui省的程式碼是 anhui_sample.php檔案:

 

    這兩個單位的程式碼都定義了同樣名字的常量、函式和類,但具體的實現細節是不一樣的。現在wisedu公司要做的事情就是要將ahcme的學生資訊轉換成anhui省監控平臺所需要的資料格式,以便進行資料上報。

Wisedu公司寫了下面的測試程式碼(test.php):

 

    這樣帶來一個問題,呼叫hello函式和例項化Student物件,我不知道是使用的是ahcme學校的程式碼,還是anhui省的程式碼。更嚴重的是,執行會報錯:

 

    這是一個嚴重錯誤(Fatal error),提示是不能重複定義hello函式。當然也會遇到類Student不能重複定義。

    怎麼解決這個問題呢?那就是給ahcme學校和anhui省的程式碼,定義在不同的名稱空間裡面。

如何定義名稱空間?

    使用namespace關鍵字定義名稱空間。

    namespace語句必須是php檔案中<?php標記下的第1個語句(declare語句除外)。

    頂級名稱空間是\,接下來是一級名稱空間,二級名稱空間,他們之間用\分隔。

    如\ncov2019\ahcme就是一個二級名稱空間,是ncov2019名稱空間的子名稱空間。

Achme學校的程式碼是 ahcme_sample.php檔案:

 

Anhui省的程式碼是 anhui_sample.php檔案:

 

    這裡使用的是二級子名稱空間,可以認為這兩個單位的專案都是新冠肺炎防控(ncov2019)這個專案的子專案。當然你也可以使用一級名稱空間(如anhui和ahcme),這由這幾個開發小組共同協商好就行。

    不建議在一個php檔案中定義多個名稱空間。

    這個時候,wisedu公司的測試程式碼就可以這樣寫:

 

    這裡,test.php沒有定義名稱空間,那他是頂級名稱空間\。那麼當前名稱空間就是\。

    這樣,就能很清楚的知道,$s1物件是ahcme學校的學生,$s2物件是anhui省的大學生了。執行結果也是這樣:

 

當然,作為wisedu公司的程式碼,他也可以定義名稱空間:

 

    這時,當前名稱空間就是ncov2019\wisedu了。不能再像這樣去定義ahcme的Student物件了:

$s1 = new ncov2019\ahcme\Student("11001", "張三");

    因為上面是相對路徑的定法。以前當前名稱空間是\,轉換成絕對路徑是\ncov2019\ahcme\Student物件,是正確的。現在當前名稱空間是ncov2019\wisedu,轉換成絕對路徑就是\ncov2019\wisedu\ncov2019\ahcme\Student物件,當然就不正確了,所以要用絕對路徑來使用Student物件:

$s1 = new \ncov2019\ahcme\Student("11001", "張三");

給名稱空間起個別名

    上面的名稱空間\ncov2019\wiseduncov2019\ahcme名字太長,經常寫的話就很費事,所以打算用個短點的名字,如ahcme。這是可以使用use關鍵字來給名稱空間起個別名:

 

除了可以使用use語句給名稱空間起別名,也可以給常量、函式、類名起個別名:

  

    總之,名稱空間就是用來解決不同軟體開發團隊間常量/函式/類的同名問題。如果遇不到命名衝突問題,完全可以不使用名稱空間。

    另外,PHP的名稱空間是從5.3版本才開始的,從個人感覺來看,他的名稱空間解決機制沒有Java和.NET的豐富和靈活。從總體來看,PHP沒有多少如淘寶、Youtube等大型專案的應用,他的主要應用還是在於中小型專案的快速構建,所以,它在一些複雜專案的管理支援上還是要欠缺一些。

    有問題,請在下方評論區留言。

(2020.3.14 0:48 by whitewin)

&n