您好,登錄后才能下訂單哦!
PHP中反射的概念是什么?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
一、前言
Reflection(反射)是Java程序開(kāi)發(fā)語(yǔ)言的特征之一,它允許運(yùn)行中的Java程序?qū)ψ陨磉M(jìn)行檢查,或者說(shuō)“自審”,并能直接操作程序的內(nèi)部屬性。這一特征在實(shí)際應(yīng)用中也許用得不是很多。
PHP從5.0開(kāi)始完美支持反射API。PHP反射可以用于觀察并修改程序在運(yùn)行時(shí)的行為。一個(gè)面向反射的(reflection-oriented)程序組件可以監(jiān)測(cè)一個(gè)范圍內(nèi)的代碼執(zhí)行情況,可以根據(jù)期望的目標(biāo)與此相關(guān)的范圍修改本身。PHP5具有完整的反射API,添加了對(duì)類(lèi)、接口、函數(shù)、方法和擴(kuò)展進(jìn)行反向工程的能力。
二、概念
反射是指在PHP運(yùn)行狀態(tài)中,擴(kuò)展分析PHP程序,導(dǎo)出或提出關(guān)于類(lèi)、方法、屬性、參數(shù)等的詳細(xì)信息,包括注釋。這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱(chēng)為反射API。
三、PHP反射的基本語(yǔ)法
實(shí)現(xiàn)反射的方法有很多,可以通過(guò)實(shí)例化一個(gè)專(zhuān)門(mén)控制類(lèi)的ReflectionClass
類(lèi)來(lái)實(shí)現(xiàn)反射,也可以在已有類(lèi)實(shí)例的情況下,通過(guò)直接實(shí)例化ReflectionMethod
類(lèi)來(lái)執(zhí)行反射方法,原理如圖:
以下是對(duì)反射類(lèi)和反射方法類(lèi)的基本用法:
1、反射類(lèi)
(1) $reflectClass = new ReflectionClass(<類(lèi)名>);
傳入類(lèi)名字符串,返回控制目標(biāo)類(lèi)的ReflectionClass類(lèi)實(shí)例;
(2) $reflectClass->getConstant(<常量名>);
傳入類(lèi)中定義了的常量名,返回常量值,可通過(guò)$reflectClass->getConstants
返回類(lèi)中所有定義的常量的數(shù)組;
(3) $class = $reflectClass->newInstance();
實(shí)例化類(lèi),返回目標(biāo)類(lèi)實(shí)例;也可通過(guò)$reflectClass->newInstanceArgs(<參數(shù)數(shù)組>)
傳入實(shí)例化的構(gòu)造函數(shù)參數(shù)進(jìn)行實(shí)例化;
2、反射方法
(1) $reflectMethod = new ReflectionMethod(<方法名>);
傳入方法名名字符串,返回控制目標(biāo)方法的ReflectionMethod類(lèi)實(shí)例;
(2) $parameters = $reflectMethod->getParameters();
獲取該類(lèi)所需的參數(shù)名,該方法返回一個(gè)包含所有參數(shù)名的二維數(shù)組;
(3) $name = $parameters->getName();
返回要執(zhí)行的方法所需參數(shù)數(shù)組的單個(gè)參數(shù)名,可通過(guò)foreach循環(huán)逐一獲取和賦值;
(4) $reflectMethod->invokeArgs(<類(lèi)實(shí)例>,<執(zhí)行該方法所需參數(shù)數(shù)組>);
傳入類(lèi)實(shí)例和方法參數(shù),執(zhí)行方法,返回執(zhí)行結(jié)果。
3、反射類(lèi)和反射方法中其他常用的用法:
ReflectionClass:
ReflectionMethod:
4、除了ReflectionClass和ReflectionMethod,我們對(duì)于類(lèi)中的參數(shù)、屬性和php服務(wù)的環(huán)境變量、擴(kuò)展等參數(shù)也是可以通過(guò)反射API的一些方法來(lái)執(zhí)行的,如下:
四、反射在實(shí)際應(yīng)用中的使用
1、反射可以用于文檔、文件生成。可以用它對(duì)文件里的類(lèi)進(jìn)行掃描,逐個(gè)生成描述文檔;
2、既然反射可以探知類(lèi)的內(nèi)部結(jié)構(gòu),那么可以用它做hook實(shí)現(xiàn)插件功能;
3、可以用于做動(dòng)態(tài)代理,在未知或者不確定類(lèi)名的情況下,動(dòng)態(tài)生成和實(shí)例化一些類(lèi)和執(zhí)行方法;
4、對(duì)于多次繼承的類(lèi),我們可以通過(guò)多次反射探索到基類(lèi)的結(jié)構(gòu),或者采用遞歸的形式反射,實(shí)現(xiàn)實(shí)例化所有繼承類(lèi),這即是PHP依賴(lài)注入的原理。
五、PHP反射的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
1、支持反射的語(yǔ)言提供了一些在低級(jí)語(yǔ)言中難以實(shí)現(xiàn)的運(yùn)行時(shí)特性。
2、可以在一定程度上避免硬編碼,提供靈活性和通用性。
3、可以作為一個(gè)第一類(lèi)對(duì)象發(fā)現(xiàn)并修改源代碼的結(jié)構(gòu)(如代碼塊、類(lèi)、方法、協(xié)議等)。
4、可以在運(yùn)行時(shí)像對(duì)待源代碼語(yǔ)句一樣計(jì)算符號(hào)語(yǔ)法的字符串(類(lèi)似JavaScript的eval()函數(shù)),進(jìn)而可將跟class或function匹配的字符串轉(zhuǎn)換成class或function的調(diào)用或引用。
5、可以創(chuàng)建一個(gè)新的語(yǔ)言字節(jié)碼解釋器來(lái)給編程結(jié)構(gòu)一個(gè)新的意義或用途。
劣勢(shì)
1、此技術(shù)的學(xué)習(xí)成本高。面向反射的編程需要較多的高級(jí)知識(shí),包括框架、關(guān)系映射和對(duì)象交互,以利用更通用的代碼執(zhí)行。
2、同樣因?yàn)榉瓷涞母拍詈驼Z(yǔ)法都比較抽象,過(guò)多地濫用反射技術(shù)會(huì)使得代碼難以被其他人讀懂,不利于合作與交流。
3、由于將部分信息檢查工作從編譯期推遲到了運(yùn)行期,此舉在提高了代碼靈活性的同時(shí),犧牲了一點(diǎn)點(diǎn)運(yùn)行效率。
4、通過(guò)深入學(xué)習(xí)反射的特性和技巧,它的劣勢(shì)可以盡量避免,但這需要許多時(shí)間和經(jīng)驗(yàn)的積累。
1、執(zhí)行速度快。2、具有很好的開(kāi)放性和可擴(kuò)展性。3、PHP支持多種主流與非主流的數(shù)據(jù)庫(kù)。4、面向?qū)ο缶幊蹋篜HP提供了類(lèi)和對(duì)象。5、版本更新速度快。6、具有豐富的功能。7、可伸縮性。8、功能全面,包括圖形處理、編碼與解碼、壓縮文件處理、xml解析等。
關(guān)于PHP中反射的概念是什么問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。