詳細解讀php的命名空間(一)

2021-08-13 22:26:28 字數 4430 閱讀 1786

php的命名空間功能已經出來很久了,但是一直以來沒怎麼深究過,這次趕著有時間所以特意翻著手冊做乙個整理和總結幫助自己完善完善,原本準備一篇寫完,但發現內容其實還是蠻多的,放一起太長看著累,所以分兩篇部落格要好些。

一:命名空間概念:命名空間是一種封裝事物的方法,類似於目錄和檔案。

命名空間解決的問題(手冊上也寫的很清楚,下面按照自己的理解簡化了):

1:解決程式編寫者自己寫的類、常量、函式和php內部的或者第三方的出現名稱衝突的情況。

2:建立別名,幫助解決類、常量、函式名稱過長的情況,幫助提高**的可讀性,另外名稱過長其實通常都是因為為了緩解第一類問題導致的。

二:如何定義命名空間

1:命名空間用關鍵字namespace宣告,同時命名空間必須位於其他**之前,包括任何非php**以及空白符(php的declare關鍵字除外),否則會丟擲乙個fatal error。

例如:

<?php

namespace index;

?>

注意1:如果命名空間namespace前沒有任何**及空白符,但還是出現fatal error,這個應該是由於bom頭導致的,去掉bom頭就可以了。

注意2:在命名空間下,雖然可以放置所有合法的php**,但是受命名空間影響的僅有類(抽象類以及traits)和介面、常量和函式。

2:與目錄和檔案的關係很象,php 命名空間也允許指定層次化的命名空間的名稱。因此,命名空間的名字可以使用分層次的方式定義,分隔符是\。

例如:

<?php

namespace index\col\file;

define('message','hello world');

?>

3:乙個檔案中可以定義多個命名空間,定義的語法有兩種,一種是簡單組合語法,另一種是大括號形式語法,另外乙個檔案定義多個命名空間的使用一般是多個檔案合併成乙個檔案的場景,但不到萬不得已最好不要這樣,因為這樣增加了**的複雜度,可讀性會降低,一般情況也沒有這種使用的必要。

簡單組合語法:

<?php

namespace index;

const instance=1;

namespace col;

const instance=2;

?>

大括號語法,乙個檔案多個命名空間,如果還需要寫上非命名空間的**,就只能用大括號語法,並且非命名空間**用namespace宣告乙個沒有名稱的命名空間,再用大括號即可:

<?php

/*命名空間index*/

namespace index

/*命名空間col*/

namespace col

/*全域性非命名空間***/

namespace

?>

4:多個不同的檔案可以定義同乙個命名空間,也就是說同乙個命名空間的內容可以分別儲存到多個不同的檔案中,這裡就不舉例了。

三:命名空間的識別原理

命名空間的使用原理有三種情況,手冊上其實說的詳細但可能因為翻譯問題導致一些凌亂,這裡我簡化一下用自己的例子梳理一下:

1:沒有限定名稱,也就是直接使用要讀取的類、常量、函式、介面名稱,這種情況會讀取該內容所屬的命名空間的類、常量、函式、介面名稱,但如果命名空間內沒有相關的資料,如果是類和介面名稱會返回fatal error,如果是函式和常量會自動讀取全域性的函式和常量,如果全域性中也沒有,才會報fatal error。

下面舉例:

<?php

/*全域性非命名空間***/

namespace

class foo

} var_dump(instance); //列印出來的是1

test(); //輸出1

foo::fool(); //輸出1

}/*命名空間index*/

namespace index

class foo

} var_dump(instance); //列印出來的是2

test(); //輸出2

foo::fool(); //輸出2

}/*命名空間col*/

namespace col

class foo

} var_dump(instance); //列印出來的是3

test(); //輸出3

foo::fool(); //輸出3

}?>

上面的例子每個命名空間裡輸出的都沒有限定名稱,所以會得到當前命名空間下設定的對應資料值。

如果當前命名空間沒有設定,函式和常量則會讀取全域性設定的對應資料值,全域性沒有對應的才會報fatal error,類和介面都會直接報fatal error,如下面**所示。

<?php

/*全域性非命名空間***/

namespace

class foo

} var_dump(instance); //列印出來的是1

test(); //輸出1

foo::fool(); //輸出1

}/*命名空間index*/

namespace index

?>

2:限定名稱,分為兩種情況,一種是包含字首的限定名稱情況,一種是包含全域性限定名稱的情況。手冊上將這兩種單獨分開了,但我覺得這兩種可以合併成一起說,他們都是有限定名稱,只是前者沒有全域性限定,後者有全域性限定。

①包含字首的限定名稱,這種字首可以有多個或者乙個層級,但最左側不能為\全域性限定詞,這種情況會讀取該**所在命名空間加上該字首限定名稱所對應資料,也就是:

所處命名空間\字首限定\名稱來讀取,如果該**是全域性沒有命名空間的,則直接用字首限定名稱來讀取,也就是:字首限定\名稱來讀取。

例項**:

<?php

/*命名空間col\index*/

namespace col\index

/*命名空間index*/

namespace index

/*命名空間col*/

namespace col

/*全域性非命名空間***/

namespace

?>

②全域性限定字首名稱:也就是在最左側有全域性操作符\進行修飾的字首限定名稱,當然也可以沒有字首限定直接全域性操作符\加上名稱也是可以的。但加上全域性操作符後就跟目錄裡的絕對路徑一樣,只會按照全域性限定後的所設定的進行讀取。

具體例項如下:

<?php

/*命名空間col\index*/

namespace col\index

/*命名空間index*/

namespace index

/*命名空間col*/

namespace col

/*全域性非命名空間***/

namespace

namespace lin

?>

四:命名空間在字串中的轉義

有時候命名空間會放在字串中使用,如果是單引號不會通過編譯器解釋,所以沒有任何問題,但是如果是雙引號,那麼就會有些意外情況了,要知道雙引號裡的內容是需要經過編譯器進行解釋然後再進行輸出的,而\在編譯器裡的解釋容易造成歧義

例如"index\name"這裡就有\n會被解釋成換行,除此之外還有很多這種造成意外的情況。

因此一般我們推薦命名空間如果要放在字串中使用,最好使用單引號,一是效率,二是安全,如果使用雙引號,則必須增加乙個\進行轉義避免歧義,例如"index\\name"這樣就沒有問題了。

隨手雙引號的舉個例子:

<?php

/*全域性非命名空間***/

namespace index\name }}

namespace

PHP 命名空間 一

無命名空間 class lister namespace my require once product.php class lister lister test 訪問本地 from my lister test 訪問全域性空間 from global前導的反斜槓告訴php從根命名空間而不是從當前命...

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

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

PHP的命名空間

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