电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

PHP反射基礎(chǔ)知識(shí)回顧

瀏覽:48日期:2022-09-09 08:31:53

反射是編程語(yǔ)言的高級(jí)特性,能在運(yùn)行時(shí)讓代碼有感知代碼的能力。PHP自5起支持反射機(jī)制,其是各種OOP框架底層實(shí)現(xiàn)的重要支撐。

反射

從一個(gè)簡(jiǎn)單的例子理解反射:人有五官四肢,但鮮有人清楚人體內(nèi)部的經(jīng)脈走向、骨骼構(gòu)造。如果你修仙順利,在丹田深處練出元嬰,那么就通過(guò)元嬰透析身體內(nèi)部的構(gòu)造。理解內(nèi)部構(gòu)造后,還可以讓元嬰指引體內(nèi)真氣在經(jīng)脈的流向,早日修成正果。

如其名,反射是(從鏡子里)照出自身。我們寫(xiě)代碼,告訴代碼怎么運(yùn)行,事件發(fā)生在編譯期。代碼運(yùn)行期間,代碼如何知道自己的結(jié)構(gòu)以及能力呢?反射機(jī)制相當(dāng)于代碼的元嬰,使代碼能夠感知自身結(jié)構(gòu),并可(部分)改變運(yùn)行行為。

與運(yùn)行時(shí)類型信息(Runtime Type Informatiion, RTTI)不同,反射重點(diǎn)在運(yùn)行時(shí)檢測(cè)、感知、改變自身的結(jié)構(gòu)和行為。反射是元編程(metaprogramming)的重要組成部分。

PHP反射API

反射不是語(yǔ)法分析,不操作表達(dá)式、代碼語(yǔ)句。反射獲取的是代碼的結(jié)構(gòu),即函數(shù)、類這些構(gòu)件的結(jié)構(gòu)。PHP中的反射API均以Reflection開(kāi)頭(接口Reflector除外),重點(diǎn)在函數(shù)和類兩種結(jié)構(gòu)。而函數(shù)可以看成類的成員函數(shù)(多一個(gè)隱式的this參數(shù))或者靜態(tài)成員函數(shù)(public類型),所以了解反射API可從類信息的ReflectionClass開(kāi)始。

ReflectionClass提供了以下獲取類基本信息的接口:

getProperties:獲取成員變量/屬性,返回一個(gè)ReflectionProperty數(shù)組;ReflectionProperty類中有對(duì)屬性詳細(xì)說(shuō)明的API:是否默認(rèn)屬性(isDefault),是否私有屬性(isPrivate)等。同時(shí)ReflectionClass還提供獲取特定類別屬性的API:getDefaultProperties,getStaticProperties; getConstants:獲取類中定義的常量; getMethods:獲取類中定義的方法,返回一個(gè)ReflectionMethod數(shù)組;ReflectionMethod將在下文講解; getInterfaces:獲取類實(shí)現(xiàn)的接口; getParentClass:獲取父類的ReflectionClass實(shí)例。

在反射中,類、接口、特性不分家,所以ReflectionClass提供類型判定API:isInterface、isTrait。

除了以上基本信息,ReflectionClass(包括ReflectionMethod/ReflectionFunction)還提供了一些不可思議的能力:

getDocComment:獲取類的文檔注釋信息; getFilename:獲取類定義的文件; getStartLine: 獲取類定義的起始行號(hào); getEndLine: 獲取類定義的結(jié)束行號(hào); getModifiers:獲取類定義的修飾符,其意義名字可通過(guò)Reflection::getModifierNames得到,例如:abstract,final。

如果說(shuō)前述的類結(jié)構(gòu)信息可以通過(guò)現(xiàn)有的API獲取(method_exits/property_exits等),上面列出的功能基本上只能通過(guò)反射API獲取(PHP文件中定義的類并且知道定義文件,可以利用token_get_all得到相同結(jié)果,但是實(shí)現(xiàn)非常復(fù)雜)。這些行為發(fā)生在運(yùn)行期間。由此可見(jiàn)反射API在分析類結(jié)構(gòu)信息功能上的強(qiáng)大。

除了ReflectionClass,ReflectionMethod和ReflectionFunction是另外反射中另外兩個(gè)重要的類。函數(shù)(function)定義在類外部,方法(method)定義在類內(nèi)部,兩者其實(shí)同源,在反射API中有共同的父類:ReflectionFunctionAbstract。ReflectionFunctionAbstract有兩者的大部分API,并且基本上是最重要的API。其中最值得關(guān)注的是其參數(shù)信息的API:getParameters。其獲取函數(shù)的參數(shù)信息,返回一個(gè)ReflectionParameter數(shù)組。結(jié)合getParameters和ReflectionParameter,函數(shù)(方法)的結(jié)構(gòu)基本上就清晰了。

API操作

知道人體構(gòu)造和體內(nèi)真氣分布,你可以引導(dǎo)真氣到手指,練成一陽(yáng)指、六脈神劍、彈指神通、九陰白骨爪等;也可以讓真氣匯聚,沖破任督二脈,開(kāi)辟洞天;還可以逆轉(zhuǎn)全身經(jīng)脈,練成蛤蟆功…內(nèi)省的好處可見(jiàn)一斑。

反射讓代碼感知自身結(jié)構(gòu),有什么好處呢?反射API提供了三種在運(yùn)行時(shí)對(duì)代碼操作的能力:

設(shè)置訪問(wèn)控制權(quán):setAccessible。可獲取私有的方法/屬性。注意:setAccessible只是讓方法/成員變量可以invoke/getValue/setValue,并不代表類定義的訪問(wèn)存取權(quán)限改變; 調(diào)用函數(shù)/方法:invoke/invokeArgs。配合獲取函數(shù)參數(shù)的API,可以安全的傳參和調(diào)用函數(shù),call_user_func(_array)的增強(qiáng)版; 不依賴構(gòu)造函數(shù)生成實(shí)例:newInstanceWithoutConstructor。

以單例來(lái)說(shuō)一下反射API的功能,單例類代碼如下:

# foo.phpclass Foo { private static $id; private static $instance; private function __construct() { ++ self::$id; fwrite(STDOUT, 'construct, instance id: ' . self::$id . 'n'); } public static function getSingleton() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; }}

在Foo類中,構(gòu)造函數(shù)是私有,獲取實(shí)例只能通過(guò)getSingleton方法,并且獲取到的是單例。但在反射API加持下,能獲取多個(gè)實(shí)例:

$instance1 = Foo::getSingleton();var_dump($instance1);$class = new ReflectionClass('Foo');$constructor = $class->getConstructor();if ((ReflectionProperty::IS_PUBLIC & $constructor->getModifiers()) === 0) { $constructor->setAccessible(true);}$instance2 = $class->newInstanceWithoutConstructor();$constructor->invoke($instance2);var_dump($instance2);# 腳本執(zhí)行結(jié)果construct, instance id: 1object(Foo)#1 (0) {}construct, instance id: 2object(Foo)#4 (0) {}

我們成功的生成了兩個(gè)實(shí)例,并調(diào)用構(gòu)造函數(shù)完成對(duì)象初始化。如果沒(méi)有反射API,這幾乎是不可能完成的工作。

除了這三種操作,反射API幾乎已無(wú)在運(yùn)行時(shí)動(dòng)態(tài)改變代碼的行為。但作為動(dòng)態(tài)語(yǔ)言,PHP內(nèi)置了將數(shù)據(jù)轉(zhuǎn)換成代碼執(zhí)行的能力(例如create_function/eval、動(dòng)態(tài)函數(shù)名調(diào)用)。而PHP的好基友JavaScript則可以隨時(shí)在運(yùn)行時(shí)改變?nèi)我夂瘮?shù)的行為:

PHP反射基礎(chǔ)知識(shí)回顧

PHP作為最好的語(yǔ)言,理應(yīng)能做到在運(yùn)行時(shí)動(dòng)態(tài)增減/改變函數(shù)定義。這就需要用到另一個(gè)PHP核心開(kāi)發(fā)者“Dmitry Zenovich”打造的大殺器:runkit拓展。這部分內(nèi)容不屬于反射,加之本人了解不深,不再詳述。

對(duì)比

整理一下反射API和函數(shù)式API在功能上的差異:

功能 函數(shù)式API 反射API 函數(shù)是否存在 function_exists ReflectionFunction 類是否存在 class_exits ReflectionClass 方法是否存在 method_exits ReflectionMethod 變量/屬性是否存在 property_exits ReflectionProperty 獲取類變量 get_class_vars ReflectionClass::getProperties 獲取類方法 get_class_methods ReflectionClass::getMethods 獲取類常量 — ReflectionClass::RegetReflectionConstant(s) 獲取函數(shù)/方法參數(shù)信息 — ReflectionFunction/Method::getParameters 獲取函數(shù)/方法返回值 — ReflectionFunction/Method::getReturnType 類使用的特性 class_uses ReflectionClass::getTraits 獲取父類 class_parents ReflectionClass::getParentClass 獲取類實(shí)現(xiàn)的接口 class_implements ReflectionClass::getInterfaceNames 獲取類所在名字空間 __NAMESPACE__ ReflectionClass::getNamespaceName 函數(shù)調(diào)用 call_user_func(_array) ReflectionMethod(Function)::invoke(Args) 獲取類名 __CLASS__/::class ReflectionClass::getName 獲取函數(shù)名 __METHOD__/__FUNCTION__ ReflectionFunction/Method::getName 獲取類/常量/變量/方法修飾符 — ReflectionClass/Constant/Property/Method::getModifiers 獲取所在文件 __FILE__ ReflectionClass/Constant/Function/Method::getFileName 獲取所在行(范圍) — ReflectionClass/Function/Method::getStartLine/getEndLine 獲取文檔 — ReflectionClass/Function/Method::getDocComment extension_loaded ReflectionZendExtension 拓展 get_loaded_extensions ReflectionExtension get_extension_funcs

從上表可以看出反射API較函數(shù)式API能提供更全面的信息。還需要注意到__FILE__這類魔術(shù)常量是編譯期的工作,不是運(yùn)行時(shí)的能力。

同時(shí)給出RTTI的函數(shù)式API和反射API在功能上的差異:

功能 函數(shù)式API 反射API 類型判斷 is_int/is_bool/is_array等 — 獲取對(duì)象的類名 get_class ReflectionObject::getName 獲取對(duì)象父類 get_parent_class ReflectionObject::getParentClass 類型/繼承檢測(cè) instanceof/is_a/is_subclass_of ReflectionObject::isInstance/isSubclassOf 生成器 — ReflectionGenerator

總結(jié)

本文對(duì)PHP中的反射機(jī)制做了簡(jiǎn)要總結(jié),并與在運(yùn)行時(shí)獲取代碼信息的函數(shù)式API做了對(duì)比。即使你token_get_all用得再熟練,preg_match等文本操作用得再順手,反射API仍有其獨(dú)到一面,值得了解。如本人之前博文“PHP中的重載”所言,有了反射,function_exits/class_exits、call_user_func這些函數(shù)應(yīng)該可以退休。但是考慮到兼容、使用便利、運(yùn)行效率等因素,許多框架仍然依賴這些API。

感謝閱讀,歡迎指正!

以上就是PHP反射知識(shí)回顧的詳細(xì)內(nèi)容,更多關(guān)于PHP 反射的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: PHP
相關(guān)文章:
主站蜘蛛池模板: 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 金属清洗剂,防锈油,切削液,磨削液-青岛朗力防锈材料有限公司 | 电动液压篮球架_圆管地埋式篮球架_移动平箱篮球架-强森体育 | 找果网 | 苹果手机找回方法,苹果iPhone手机丢了找回,认准找果网! | 雨燕360体育免费直播_雨燕360免费NBA直播_NBA篮球高清直播无插件-雨燕360体育直播 | 盘煤仪,盘料仪,盘点仪,堆料测量仪,便携式激光盘煤仪-中科航宇(北京)自动化工程技术有限公司 | 广东青藤环境科技有限公司-水质检测| 水平垂直燃烧试验仪-灼热丝试验仪-漏电起痕试验仪-针焰试验仪-塑料材料燃烧检测设备-IP防水试验机 | 安徽千住锡膏_安徽阿尔法锡膏锡条_安徽唯特偶锡膏_卡夫特胶水-芜湖荣亮电子科技有限公司 | 天津热油泵_管道泵_天津高温热油泵-天津市金丰泰机械泵业有限公司【官方网站】 | 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 欧美日韩国产一区二区三区不_久久久久国产精品无码不卡_亚洲欧洲美洲无码精品AV_精品一区美女视频_日韩黄色性爱一级视频_日本五十路人妻斩_国产99视频免费精品是看4_亚洲中文字幕无码一二三四区_国产小萍萍挤奶喷奶水_亚洲另类精品无码在线一区 | 山西3A认证|太原AAA信用认证|投标AAA信用证书-山西AAA企业信用评级网 | 诺冠气动元件,诺冠电磁阀,海隆防爆阀,norgren气缸-山东锦隆自动化科技有限公司 | 掺铥光纤放大器-C/L波段光纤放大器-小信号光纤放大器-合肥脉锐光电技术有限公司 | 呼末二氧化碳|ETCO2模块采样管_气体干燥管_气体过滤器-湖南纳雄医疗器械有限公司 | 紫外线老化试验箱_uv紫外线老化试验箱价格|型号|厂家-正航仪器设备 | 播音主持培训-中影人教育播音主持学苑「官网」-中国艺考界的贵族学校 | 喷码机,激光喷码打码机,鸡蛋打码机,手持打码机,自动喷码机,一物一码防伪溯源-恒欣瑞达有限公司 | 精密冲床,高速冲床等冲压设备生产商-常州晋志德压力机厂 | 砍排机-锯骨机-冻肉切丁机-熟肉切片机-预制菜生产线一站式服务厂商 - 广州市祥九瑞盈机械设备有限公司 | 智慧食堂_食堂管理系统_食堂订餐_食堂消费系统—客易捷 | 不锈钢水箱厂家,不锈钢保温水箱-山东桑特供水设备 | 专业甜品培训学校_广东糖水培训_奶茶培训_特色小吃培训_广州烘趣甜品培训机构 | 浙江华锤电器有限公司_地磅称重设备_防作弊地磅_浙江地磅售后维修_无人值守扫码过磅系统_浙江源头地磅厂家_浙江工厂直营地磅 | 卡诺亚轻高定官网_卧室系统_整家定制_定制家居_高端定制_全屋定制加盟_定制家具加盟_定制衣柜加盟 | 新能源汽车教学设备厂家报价[汽车教学设备运营18年]-恒信教具 | 数年网路-免费在线工具您的在线工具箱-shuyear.com | 活性氧化铝球|氧化铝干燥剂|分子筛干燥剂|氢氧化铝粉-淄博同心材料有限公司 | 深圳希玛林顺潮眼科医院(官网)│深圳眼科医院│医保定点│香港希玛林顺潮眼科中心连锁品牌 | 空气能暖气片,暖气片厂家,山东暖气片,临沂暖气片-临沂永超暖通设备有限公司 | 激光内雕_led玻璃_发光玻璃_内雕玻璃_导光玻璃-石家庄明晨三维科技有限公司 激光内雕-内雕玻璃-发光玻璃 | 上海洗地机-洗地机厂家-全自动洗地机-手推式洗地机-上海滢皓洗地机 | 渗透仪-直剪仪-三轴仪|苏州昱创百科| ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | 郑州墨香品牌设计公司|品牌全案VI设计公司 | 热工多功能信号校验仪-热电阻热电偶校验仿真仪-金湖虹润仪表 | 一技任务网_有一技之长,就来技术任务网 | 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 贵州成人高考网_贵州成考网| 预制直埋蒸汽保温管-直埋管道-聚氨酯发泡保温管厂家 - 唐山市吉祥保温工贸有限公司 |