PHP關(guān)鍵特性之命名空間實(shí)例詳解
命名空間主要是為了解決代碼中類和函數(shù)可能存在沖突的問題,而這個(gè)特性其他語(yǔ)言一早就有,PHP則是姍姍來(lái)遲,它的出現(xiàn)催生了 PSR-4 的誕生,從而也催生了 Composer 的興起,所以是非常重要的特性。
命名空間的定義
命名空間是一個(gè)容器,這個(gè)容器主要是為了識(shí)別其下的類和函數(shù)。一旦定義了命名空間,它下面的代碼就屬于這個(gè)命名空間了,所以命名空間的定義要在代碼的最開始行。
對(duì)于同一個(gè)包來(lái)說(shuō),同一個(gè)命名空間或者子命名空間的代碼沒有必要在一個(gè) PHP 文件中定義,子命名空間下的代碼是為了完成特定模塊的工作,組合起來(lái)就是一個(gè)包完整的命名空間。
假如編寫的代碼沒有定義命名空間,那說(shuō)明它屬于全局的命名空間(\ 符號(hào)),所以能夠直接引用類或者函數(shù)(不用添加 \ 符號(hào))。
引用命名空間標(biāo)識(shí)符的三種方式
(1)Fully-qualified name
類似于操作系統(tǒng)上的絕對(duì)路徑,而且是完整的路徑,所以在理解的時(shí)候不會(huì)有誤解。
比如在 new \A\B\C ,那么 C 就被會(huì)解析到 A\B 命名空間下的 C 類。
(2)Qualified name
類似于操作系統(tǒng)上的相對(duì)路徑,它包含部分名字并被引用到當(dāng)前的命名空間。
比如 B\C() 在命名空間 A 下調(diào)用,則最終引用的命名空間就是 A\B\C()。
(3)Unqualified name
類似于Qualified name,但是沒包括子命名空間。
比如 C() 在命名空間 A\B 下調(diào)用,則最終引用的命名空間就是 A\B\C()。
通過(guò)一個(gè)例子來(lái)說(shuō)明三種引用方式:
namespace \Example; require_once "fnction.php"; class ClassA {} function Function() {} //完全限定名稱 \Example\Function(); \Example\B\Function(); //限定名稱 B\Function(); //指向 \Example\B\Function(); //非限定名稱 $test = new ClassA(); //resolves to \Example\ClassA Function(); //指向 \Example\Function
注意:
•Inside a namespace,假如在 current scope 沒有發(fā)現(xiàn)函數(shù)和常量的定義,PHP 不會(huì)報(bào)錯(cuò)。而是去全局命名空間中尋找。
•Inside a namespace,假如在 current scope 沒有發(fā)現(xiàn)類的定義,則 PHP 會(huì)直接報(bào)錯(cuò),不會(huì)去全局域中找對(duì)應(yīng)的類,所以假如你需要引用一個(gè) internal 或用戶自定義的類,必須使用完全限定名稱。
先舉個(gè)簡(jiǎn)單的例子,首先編寫一段代碼(定義在命名空間下),命名為 function.php :
namespace Foo\Bar\subnamespace; const FOO = 1; function foo() { return "foo\r\n"; } class foo { static function staticmethod() { return __METHOD__ . "\r\n" ; } function foofunction() { return __METHOD__ . "\r\n" ; } }
再編寫一段代碼 test.php,也是處于命名空間之下的代碼:
namespace secondsp; include 'function.php'; class foo { function foofunction() { return __METHOD__ . "\r\n" ; } } function is_file($file) { return true ; } //非限定名稱:實(shí)例化secondsp\foo類對(duì)象 $obj = new foo; echo $obj->foofunction(); //實(shí)例化Foo\Bar\subnamespace\foo 類對(duì)象 $obj = new Foo\Bar\subnamespace\foo ; echo $obj->foofunction(); //代碼會(huì)報(bào)錯(cuò),在命名空間內(nèi)部,假如無(wú)法找到當(dāng)前命名空間下的類,則會(huì)報(bào)錯(cuò) //$obj = new ArrayObject(array(1)); $obj = new \ArrayObject(array(1)); //在命名空間內(nèi)部,假如無(wú)法找到當(dāng)前命名空間下的函數(shù)或者常量,則會(huì)尋找 native function echo strlen("nihao"); //引用當(dāng)前命名空間下的函數(shù) var_dump(is_file('nihao')); //True //引用全局函數(shù) var_dump(\is_file('nihao')); //False
導(dǎo)入,別名
假如要使用的命名空間層級(jí)很長(zhǎng)且數(shù)量很多,那么在使用的時(shí)候特別麻煩,所以可以使用 use 關(guān)鍵字導(dǎo)入命名空間、類、常量、函數(shù)等,然后可以使用它們直接引用完整的名稱。而 alias 關(guān)鍵字可以給導(dǎo)入的類和函數(shù)等重命名。
舉個(gè)例子如何使用 use 關(guān)鍵字,該代碼處于全局命名空間之下:
include 'function.php'; use Foo\Bar\subnamespace\foo ; $obj = new foo; echo $obj->foofunction(); use Foo\Bar\subnamespace\foo as aliasfunname; $obj = new aliasfunname; echo $obj->foofunction(); use Foo\Bar\subnamespace ; $obj = new subnamespace\foo ; echo $obj->foofunction(); use Foo\Bar\subnamespace as aliasname; $obj = new aliasname\foo ; echo $obj->foofunction(); //由于調(diào)用代碼并不在命名空間內(nèi),所以對(duì)于全局的類,無(wú)需引入使用 $obj = new ArrayObject(array(1)); //導(dǎo)入一個(gè)函數(shù) use function Foo\Bar\subnamespace\foo ; echo foo(); use function Foo\Bar\subnamespace\foo as func; echo func(); use const Foo\Bar\subnamespace\FOO; //echo FOO;
總結(jié):
•和 Python 不一樣,PHP 中的命名空間是語(yǔ)義上的一種概念,和具體代碼的位置、布局沒有關(guān)系,換句話說(shuō),使用命名空間的代碼需要自己引入庫(kù)文件(所有文件),至于庫(kù)文件如何組織無(wú)所謂;而在 Python 中,假如模塊或包中有一個(gè) __init__.py 文件,則 Python 解析器會(huì)自動(dòng)引入包或所有模塊的文件。
•PHP 中作用域的概念很弱化,全局域和局部域分的很清楚,比如在函數(shù)或類中無(wú)法引用全局空間中的變量。而在命名空間則不同,定義命名空間的代碼,假如找不到對(duì)應(yīng)命名空間下的常量和函數(shù),則會(huì)使用全局的常量和函數(shù);而假如找不到對(duì)應(yīng)名命名空間下的類(包括自定義類),則代碼直接報(bào)錯(cuò)。
•通過(guò) use 關(guān)鍵字使用命名空間的,無(wú)須通過(guò)完全限定名稱的方式(\ 符號(hào))導(dǎo)入,因?yàn)?PHP 已經(jīng)假設(shè)導(dǎo)入的是完全限定的命名空間。
•通過(guò) use 關(guān)鍵字可以導(dǎo)入常量、函數(shù)、類、接口、其他命名空間。
•命名空間是一種語(yǔ)言特性,為了追求更有效的使用,應(yīng)該有一種使用規(guī)范和自動(dòng)加載機(jī)制,這就是 PSR-4 規(guī)范。
以上所述是小編給大家介紹的PHP關(guān)鍵特性之命名空間實(shí)例詳解,希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
Laravel框架控制器的request與response用法示例
這篇文章主要介紹了Laravel框架控制器的request與response用法,結(jié)合實(shí)例形式分析了Laravel框架控制器的request與response發(fā)送請(qǐng)求及響應(yīng)請(qǐng)求的相關(guān)操作技巧,需要的朋友可以參考下2019-09-09Zend?Framework框架的校驗(yàn)器使用使用示例(自定義校驗(yàn)器和校驗(yàn)器鏈)
這篇文章主要介紹了Zend?Framework框架的校驗(yàn)器使用使用示例(自定義校驗(yàn)器和校驗(yàn)器鏈),需要的朋友可以參考下2014-03-03PHP 表單提交及處理表單數(shù)據(jù)詳解及實(shí)例
本文章向大家介紹表單的一些知識(shí)點(diǎn),然后介紹PHP是如何接收表單數(shù)據(jù)并如何處理表單數(shù)據(jù),文章以一個(gè)發(fā)送郵件的表單實(shí)例來(lái)向大家講解表單提交及php如何處理表單數(shù)據(jù),需要的朋友可以參考下2016-12-12使用PHP和JavaScript判斷請(qǐng)求是否來(lái)自微信內(nèi)瀏覽器
這篇文章主要介紹了使用PHP和JavaScript判斷請(qǐng)求是否來(lái)自微信內(nèi)瀏覽器,包括在手機(jī)端的程序上使用微信的分享JS腳本的方法,需要的朋友可以參考下2015-08-08php 使用fopen函數(shù)創(chuàng)建、打開文件詳解及實(shí)例代碼
這篇文章主要介紹了php 使用fopen函數(shù)創(chuàng)建、打開文件詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09php 利用array_slice函數(shù)獲取隨機(jī)數(shù)組或前幾條數(shù)據(jù)
這篇文章主要介紹了php 利用array_slice函數(shù)獲取隨機(jī)數(shù)組或前幾條數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2015-09-09Yii2.0表關(guān)聯(lián)查詢實(shí)例分析
這篇文章主要介紹了Yii2.0表關(guān)聯(lián)查詢的方法,結(jié)合實(shí)例形式分析了Yii中關(guān)聯(lián)查詢的實(shí)現(xiàn)方法與相關(guān)使用技巧,需要的朋友可以參考下2016-07-07微信小程序之支付后調(diào)用SDK的異步通知及驗(yàn)證處理訂單方法
下面小編就為大家分享一篇微信小程序之支付后調(diào)用SDK的異步通知及驗(yàn)證處理訂單方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2018-01-01