php的命名空間

2021-09-25 01:30:32 字數 3717 閱讀 8173

問:命名空間是什麼?它有什麼用?

看一下官方給出來的解釋:php 命名空間可以解決以下兩類問題:

1:使用者編寫的**與php內部的類/函式/常量或第三方類/函式/常量之間的名字衝突。

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

對於官方的解釋,用乙個形象化的例子來表達就是:在乙個學校裡有很多與你同名的同學,此外學校有個嚴格規定,同名的學生是不允許分配在同乙個班級裡面的(雖然現實不是,這裡是為了更貼切**中不允許同名函式和類以及常量存在這一情況,而這麼設定的),這些同學呢,有的在不同年級有的在不同級部,當然肯定不在乙個班裡面。那麼我們怎麼找到他們呢?就是通過學校年級級部班,定位到這也就跑不了你了,當然除了學校還有其他單位,那就可以模擬到第三方啦。綜上所述,命名空間就是給**乙個位址,讓其他**能夠找到,能夠進行聯絡。

問:那怎麼建立(命名) 乙個命名空間呢?有什麼要注意的地方麼?

答:很簡單,通過namespace關鍵字就能命名乙個空間。

注意的地方有以下這麼幾點

1:命名空間首字元不能是數字,必須是字母或者是下劃線,否則會報出fatal error。

2:如果乙個檔案中包含命名空間,它必須在其它所有**之前宣告命名空間。在宣告命名空間之前唯一合法的**是用於定義原始檔編碼方式的 declare 語句。(例如declare(encoding='utf-8'); )所有非 php **包括空白符都不能出現在命名空間的宣告之前。

3:可以在乙個檔案中建立多個命名空間,建議對每個命名空間使用{}來以示範圍,當然也可以不加,但這樣閱讀性不好。將全域性的非命名空間中的**與命名空間中的**組合在一起(在乙個檔案中),只能使用大括號形式的語法。全域性**必須用乙個不帶名稱的 namespace 語句加上大括號括起來

4:預設情況下,所有常量、類和函式名都放在全域性空間下,就和php支援命名空間之前一樣。

5:define在命名空間內設定的常量預設是全域性的

問:我看到有的命名空間名稱還有\符號,這是幹啥的?

答:這個看著像不像資料夾的路勁,哈哈,沒錯,命名空間和資料夾很類似。這東西叫子命名空間,模擬就是子檔案目錄。例如namespace myproject\sub\level;  

問:那怎麼引用乙個命名空間或其下的類呢?

答:引用其實很好引用,只不過在不同的場景下有不同的解析方式需注意。這也就把引用方式分了類:

1:非限定名稱。(往往用在use到類名上),沒有使用命名空間。

2:限定名稱。(往往用在use命名空間),使用時類前面存在命名空間名

3:完全限定名稱。是以\開頭的,可以有命名空間也可以沒有。

注意:命名空間解析方法,除了完全限定名稱將會原封不動的按照字面解析,其餘的(非限定名稱和限定名稱)都遵循匯入原則(use套路)或者拼接原則(就是所處空間+字面空間)。

如果命名空間中的函式或常量未定義,則該非限定的函式名稱或常量名稱會被解析為全域性函式名稱或常量名稱。

這種帶命名空間的類都是從庫中(也就是有乙個基礎路徑)開始。\只出現在呼叫和use中。

在命名空間中動態訪問其他命名空間元素時,注意因為在動態的類名稱、函式名稱或常量名稱中,限定名稱和完全限定名稱沒有區別,因此其前導的反斜槓是不必要的。這個知識點在框架的自動載入中常常用到。

舉個栗子:兩個使用命名空間的檔案,裡面各有乙個hello類和sayhello方法。兩個檔案分別用a、b來表示。假設現在是a引用b,在a中使用非限制性名稱,則呼叫的的是a,當然也可以使用完全限定名稱來呼叫a,限制性名稱肯定是無法呼叫自身的了。那如果在a中呼叫b的方法呢,可以採用完全限定名稱(這個百分百可以)或限制性名稱(這個要求路徑有相對應關係),如果二者在相同的命名空間下,則可用非限定名稱!

訪問命名空間中元素的方式(沒有use時,對應use時,走use的規則)

1)非限定名稱(不帶任何字首)。$obj = new user(),解析為$obj = new current\user()

2)限定名稱(帶相對空間字首)。$obj = new home\user(),解析為$obj = new current\home\user()

3)完全限定名稱(從根空間開始)。$obj = new \home\user(),解析為$obj = new \home\user()

問:怎麼訪問當前命名空間的元素?

答:有兩種方式;

第一種,使用__namespace__。第二種使用namespace。

問:這兩種有什麼區別麼?

答:效果是一樣的,只是用法不同。

直接使用namespace就像類中使用self是一樣的,放在最前面然後用斜槓拼接上元素全域性空間(不帶命名空間的)下也可以這樣使用。

__namespace__則是乙個魔術常量,它代表這當前**所在的命名空間下的名稱。如果是全域性空間(不帶命名空間的)這個常量就是空字串。常用於動態建立名稱

問:怎麼引入別的命名空間呢?又怎麼給他起個別名呢?

答:引入用use,起別名用use+as.

事實上,use本身預設了最後乙個路徑為別名的!

use my\full\nsname as nsname

與use my\full\nsname

是一樣的;

也可以引入乙個全域性類,如use \arrayobject;

問:有沒有乙個綜述或者規則來說明這些名稱的解析原理?

答:有!官網給總結的就很到位!

名稱解析遵循下列規則:(一般就是匯入命名空間或其中的類元素)

1:對完全限定名稱的函式,類和常量的呼叫在編譯時解析。例如 new \a\b 解析為類 a\b。(就是原封不動)

2:所有的非限定名稱和限定名稱(非完全限定名稱)根據當前的匯入規則在編譯時進行轉換。例如,如果命名空間 a\b\c 被匯入為 c,那麼對 c\d\e() 的呼叫就會被轉換為 a\b\c\d\e()。(就是匯入原則)

3:在命名空間內部,所有的沒有根據匯入規則轉換的限定名稱均會在其前面加上當前的命名空間名稱。例如,在命名空間 a\b 內部呼叫 c\d\e(),則 c\d\e() 會被轉換為 a\b\c\d\e() 。

4:非限定類名根據當前的匯入規則在編譯時轉換(用全名代替短的匯入名稱)。例如,如果命名空間 a\b\c 匯入為c,則 new c() 被轉換為 new a\b\c() 。(2的細說)

5:在命名空間內部(例如a\b),對非限定名稱的

函式呼叫是在執行時解析的。例如對函式 foo() 的呼叫是這樣解析的:

(1)在當前命名空間中查詢名為 a\b\foo() 的函式

(2)嘗試查詢並呼叫全域性(global) 空間中的函式 foo()。

----------------------------對於類,沒有匯入規則的,針對3的細說---------------------------------------

6:在命名空間(例如a\b)內部對非限定名稱或限定名稱

類(非完全限定名稱)的呼叫是在執行時解析的。下面是呼叫 new c() 及 new d\e() 的解析過程: 

new c()的解析:

在當前命名空間中查詢a\b\c類。

嘗試自動裝載類a\b\c。

new d\e()的解析:

在類名稱前面加上當前命名空間名稱變成:a\b\d\e,然後查詢該類。

嘗試自動裝載類 a\b\d\e。 

7:為了引用全域性命名空間中的全域性類,必須使用完全限定名稱 new \c()。

最後個人評述:命名空間就是用來組織**結構的,方便管理還解決衝突。至於常用點就是use和自動載入機制的配合,使得類載入變得無比強大。但對閱讀上可能帶來一點麻煩,但是讀懂了命名空間的原理,也就小意思了。主要在非限定名稱和限定名稱解析的規則上,這點常用,懂了之後也就沒什麼了

php 命名空間,PHP使用命名空間

介紹 命名空間中的類,函式或常量可以通過以下方式使用 在當前命名空間中使用類 指定相對於當前命名空間的命名空間 提供命名空間的全限定名稱 從當前命名空間 在此示例中,從test1.php載入了命名空間。沒有命名空間引用的函式或類名稱將訪問當前命名空間中的功能或類名稱 示例 test1.php nam...

PHP的命名空間

php的命名空間 namespace 是php5.3之後才有的。這個概念在c 中已經很早就有了,php中的namespace其實和c 的概念是一樣的。假設如果不使用namespace,那麼每個類在乙個專案中的名字就必須是固定的。因為php在new的時候不管是呼叫autoload還是呼叫已載入過的類,...

php的命名空間

允許通過別名引用或匯入外部的完全限定名稱,是命名空間的乙個重要特徵。這有點類似於在類 unix 檔案系統中可以建立對其它的檔案或目錄的符號連線。php 命名空間支援 有兩種使用別名或匯入方式 為類名稱使用別名,或為命名空間名稱使用別名。注意php不支援匯入函式或常量。useexample 1 使用u...