摘要:反射機(jī)制反射機(jī)制從開(kāi)始支持,做業(yè)務(wù)開(kāi)發(fā)的話(huà)應(yīng)該很少接觸反射。我的理解就是反射機(jī)制能拿到類(lèi)里面的屬性方法,和的也可以以上是官方文檔中給出的東西,說(shuō)實(shí)話(huà)我看了感覺(jué)沒(méi)什么感覺(jué)。在容器成員變量中數(shù)組維護(hù)這個(gè)類(lèi),反射實(shí)例調(diào)用構(gòu)造函數(shù),獲取返回值。
PHP反射機(jī)制
反射PHP反射機(jī)制從PHP5開(kāi)始支持,做業(yè)務(wù)開(kāi)發(fā)的話(huà)應(yīng)該很少接觸反射。我其實(shí)也是接觸不多,最近在學(xué)習(xí)laravel的"優(yōu)雅",就接觸了到它其中的反射用法,已經(jīng)我自己的看法想法。
按照之前的套路,我們來(lái)看一下官方手冊(cè),官方是怎么說(shuō)的。
Reflection
PHP 5 具有完整的反射 API,添加了對(duì)類(lèi)、接口、函數(shù)、方法和擴(kuò)展進(jìn)行反向工程的能力。 此外,反射 API 提供了方法來(lái)取出函數(shù)、類(lèi)和方法中的文檔注釋。我的理解就是php反射機(jī)制能拿到類(lèi)里面的屬性方法,private 和 protected的也可以
以上是官方文檔中給出的東西,說(shuō)實(shí)話(huà)我看了感覺(jué)沒(méi)什么感覺(jué)。
能get到的點(diǎn)就是我們能夠通過(guò)這個(gè)窺探一個(gè)類(lèi)所有信息,就像在別人的窗上桶了一個(gè)洞一樣。
我應(yīng)該怎么用,或者基于什么場(chǎng)景去用呢?這還是很傷的。
laravel中的反射laravel整個(gè)框架設(shè)計(jì)的"優(yōu)雅"就是在于container、IOC、依賴(lài)注入。我們來(lái)看一下容器中一段關(guān)于反射的代碼:
IlluminateContainerContainer:
/** * Instantiate a concrete instance of the given type. * * @param string $concrete * @param array $parameters * @return mixed * * @throws IlluminateContractsContainerBindingResolutionException */ public function build($concrete, array $parameters = []) { // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be // used as resolvers for more fine-tuned resolution of these objects. if ($concrete instanceof Closure) { return $concrete($this, $parameters); } $reflector = new ReflectionClass($concrete); // If the type is not instantiable, the developer is attempting to resolve // an abstract type such as an Interface of Abstract Class and there is // no binding registered for the abstractions so we need to bail out. if (! $reflector->isInstantiable()) { if (! empty($this->buildStack)) { $previous = implode(", ", $this->buildStack); $message = "Target [$concrete] is not instantiable while building [$previous]."; } else { $message = "Target [$concrete] is not instantiable."; } throw new BindingResolutionException($message); } $this->buildStack[] = $concrete; $constructor = $reflector->getConstructor(); // If there are no constructors, that means there are no dependencies then // we can just resolve the instances of the objects right away, without // resolving any other types or dependencies out of these containers. if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } $dependencies = $constructor->getParameters(); // Once we have all the constructor"s parameters we can create each of the // dependency instances and then use the reflection instances to make a // new instance of this class, injecting the created dependencies in. $parameters = $this->keyParametersByArgument( $dependencies, $parameters ); $instances = $this->getDependencies( $dependencies, $parameters ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances); }
就是實(shí)現(xiàn)綁定類(lèi)的方法,build方法。下面我們就來(lái)分析一下:
參數(shù):$concreate string 類(lèi)似于Model::class這種嘛,不難理解。$parameters array 參數(shù) 更不難理解了吧。
判斷 $concreate 是否是匿名類(lèi)(閉包),是匿名類(lèi)就執(zhí)行這個(gè)函數(shù).
創(chuàng)建反射類(lèi),去映射這個(gè)類(lèi)。
判斷這個(gè)類(lèi)能否被實(shí)例化,也就是看構(gòu)造函數(shù)是否是private。否就拋出出異常。
在容器成員變量中數(shù)組維護(hù)這個(gè)類(lèi),反射實(shí)例調(diào)用構(gòu)造函數(shù),獲取返回值。
判斷返回值是否為空,如果為空就說(shuō)明不需要參數(shù)依賴(lài),那么就直接實(shí)例化。否則就獲取構(gòu)造函數(shù)的參數(shù)依賴(lài),將傳入的參數(shù)和依賴(lài)參數(shù)進(jìn)行對(duì)照。
最后,在調(diào)用newInstanceArgs進(jìn)行實(shí)例化,之后返回實(shí)例。
后記其實(shí)在上面這個(gè)laravel中的例子已經(jīng)很好的闡明了反射機(jī)制的使用方式,或許你現(xiàn)在的業(yè)務(wù)場(chǎng)景還未必能夠使用到這種機(jī)制。但是,當(dāng)碰到的時(shí)候請(qǐng)記得還有這種方式能夠使用。
當(dāng)你需要去實(shí)例化一個(gè)類(lèi),但是這個(gè)類(lèi)對(duì)你來(lái)說(shuō)完全就是封閉或者說(shuō)是未知的,你可以創(chuàng)建反射來(lái)與映射這個(gè)類(lèi),通過(guò)一系列的探測(cè)來(lái)最終實(shí)例化這個(gè)類(lèi),尤其還在動(dòng)態(tài)運(yùn)行中的。
基于這種機(jī)制,其實(shí)可以玩出很多的花樣。比如說(shuō)能夠自動(dòng)生成文檔。
實(shí)現(xiàn)MVC這種架構(gòu),使用反射自動(dòng)調(diào)用實(shí)現(xiàn)
$class = new ReflectionClass(ucfirst($controller)); $controller = $class->newInstance(); if ($class->hasMethod($method)) { $method = $class->getMethod($method); $method->invokeArgs($controller, $arguments); } else { throw new Exception("{$controller} controller method {$method} not exists!"); }
實(shí)現(xiàn)單元測(cè)試
$class = new ReflectionClass($class); if ($class->hasMethod($method)) { $method = $class->getMethod($method); $object = $class->newInstance(); $class = $method->invokeArgs(new $object, $params); var_dump($res === $assert); }
laravel中的反射幫助它解決DI容器的依賴(lài)注入的問(wèn)題。
還有很多好玩的等著你自己去嘗試,這種機(jī)制究竟能玩出多少花樣,就看你自己怎么玩了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/25751.html
1.查看類(lèi)屬性以及方法 single.php class single { private static $instance; public function __construct() {} /**@return single */ public static function getInstance() { if(!isset(self::$i...
摘要:反射提供給面向?qū)ο缶幊炭梢宰允〉哪芰Γ捶瓷洹T诤?jiǎn)單工廠(chǎng)模式中,根據(jù)傳遞的參數(shù)來(lái)返回不同的類(lèi)的實(shí)例簡(jiǎn)單工廠(chǎng)模式又稱(chēng)為靜態(tài)工廠(chǎng)方法模式。也就是簡(jiǎn)單工廠(chǎng)模式工廠(chǎng)工廠(chǎng)類(lèi)。PHP高級(jí)特性-反射以及工廠(chǎng)設(shè)計(jì)模式的結(jié)合使用 [結(jié)合 Laravel-Admin 代碼實(shí)例講解]利用反射來(lái)實(shí)現(xiàn)工廠(chǎng)模式的生產(chǎn)而無(wú)需創(chuàng)建特定的工廠(chǎng)類(lèi)本文地址http://janrs.com/?p=833轉(zhuǎn)載無(wú)需經(jīng)過(guò)作者本人授權(quán)轉(zhuǎn)載...
摘要:判斷是否存在構(gòu)造函數(shù),不存在直接實(shí)例化,存在則通過(guò)來(lái)獲取輸入函數(shù),并有相應(yīng)的方法解決依賴(lài)參數(shù)問(wèn)題,實(shí)現(xiàn)依賴(lài)注入。 Laravel 框架關(guān)鍵技術(shù)解析·讀書(shū)筆記(一) 第一章 入口文件 請(qǐng)求訪(fǎng)問(wèn)的入口文件,主要完成幾部分工作,分別是: 自動(dòng)加載函數(shù)的添加 服務(wù)器實(shí)例化與服務(wù)注冊(cè) 路由加載 請(qǐng)求實(shí)例化與路由分發(fā) 相應(yīng)生成與發(fā)送 其中,自動(dòng)加載函數(shù)用于包含引用文件,改文件是composer...
摘要:簡(jiǎn)介是才有的新功能,它是用來(lái)導(dǎo)出或提取出關(guān)于類(lèi)方法屬性參數(shù)等的詳細(xì)信息,包括注釋。 簡(jiǎn)介 PHP Reflection API是PHP5才有的新功能,它是用來(lái)導(dǎo)出或提取出關(guān)于類(lèi)、方法、屬性、參數(shù)等的詳細(xì)信息,包括注釋。 class Reflection { } interface Reflector { } class ReflectionException extends Exce...
摘要:發(fā)現(xiàn)大量的使用了反射機(jī)制。下面就來(lái)簡(jiǎn)單看看一些反射的應(yīng)用獲得反射下面我們來(lái)通過(guò)這個(gè)反射來(lái)得到的私有屬性得到結(jié)果得到這樣我們就可以很輕松的獲得的私有屬性了。最后通過(guò)執(zhí)行該方法反射還有很多可用的方法,這里就不一一說(shuō)了。 這幾天在看laravel框架的核心代碼。發(fā)現(xiàn)大量的使用了反射機(jī)制。下面就來(lái)簡(jiǎn)單看看一些反射的應(yīng)用 class A { private $_foo = this i...
閱讀 1254·2021-11-08 13:25
閱讀 1447·2021-10-13 09:40
閱讀 2779·2021-09-28 09:35
閱讀 743·2021-09-23 11:54
閱讀 1135·2021-09-02 15:11
閱讀 2438·2019-08-30 13:18
閱讀 1675·2019-08-30 12:51
閱讀 2694·2019-08-29 18:39