摘要:反射機制反射機制從開始支持,做業(yè)務開發(fā)的話應該很少接觸反射。我的理解就是反射機制能拿到類里面的屬性方法,和的也可以以上是官方文檔中給出的東西,說實話我看了感覺沒什么感覺。在容器成員變量中數(shù)組維護這個類,反射實例調(diào)用構(gòu)造函數(shù),獲取返回值。
PHP反射機制
反射PHP反射機制從PHP5開始支持,做業(yè)務開發(fā)的話應該很少接觸反射。我其實也是接觸不多,最近在學習laravel的"優(yōu)雅",就接觸了到它其中的反射用法,已經(jīng)我自己的看法想法。
按照之前的套路,我們來看一下官方手冊,官方是怎么說的。
Reflection
PHP 5 具有完整的反射 API,添加了對類、接口、函數(shù)、方法和擴展進行反向工程的能力。 此外,反射 API 提供了方法來取出函數(shù)、類和方法中的文檔注釋。我的理解就是php反射機制能拿到類里面的屬性方法,private 和 protected的也可以
以上是官方文檔中給出的東西,說實話我看了感覺沒什么感覺。
能get到的點就是我們能夠通過這個窺探一個類所有信息,就像在別人的窗上桶了一個洞一樣。
我應該怎么用,或者基于什么場景去用呢?這還是很傷的。
laravel中的反射laravel整個框架設計的"優(yōu)雅"就是在于container、IOC、依賴注入。我們來看一下容器中一段關于反射的代碼:
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); }
就是實現(xiàn)綁定類的方法,build方法。下面我們就來分析一下:
參數(shù):$concreate string 類似于Model::class這種嘛,不難理解。$parameters array 參數(shù) 更不難理解了吧。
判斷 $concreate 是否是匿名類(閉包),是匿名類就執(zhí)行這個函數(shù).
創(chuàng)建反射類,去映射這個類。
判斷這個類能否被實例化,也就是看構(gòu)造函數(shù)是否是private。否就拋出出異常。
在容器成員變量中數(shù)組維護這個類,反射實例調(diào)用構(gòu)造函數(shù),獲取返回值。
判斷返回值是否為空,如果為空就說明不需要參數(shù)依賴,那么就直接實例化。否則就獲取構(gòu)造函數(shù)的參數(shù)依賴,將傳入的參數(shù)和依賴參數(shù)進行對照。
最后,在調(diào)用newInstanceArgs進行實例化,之后返回實例。
后記其實在上面這個laravel中的例子已經(jīng)很好的闡明了反射機制的使用方式,或許你現(xiàn)在的業(yè)務場景還未必能夠使用到這種機制。但是,當碰到的時候請記得還有這種方式能夠使用。
當你需要去實例化一個類,但是這個類對你來說完全就是封閉或者說是未知的,你可以創(chuàng)建反射來與映射這個類,通過一系列的探測來最終實例化這個類,尤其還在動態(tài)運行中的。
基于這種機制,其實可以玩出很多的花樣。比如說能夠自動生成文檔。
實現(xiàn)MVC這種架構(gòu),使用反射自動調(diào)用實現(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!"); }
實現(xiàn)單元測試
$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容器的依賴注入的問題。
還有很多好玩的等著你自己去嘗試,這種機制究竟能玩出多少花樣,就看你自己怎么玩了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/25751.html
1.查看類屬性以及方法 single.php class single { private static $instance; public function __construct() {} /**@return single */ public static function getInstance() { if(!isset(self::$i...
摘要:反射提供給面向?qū)ο缶幊炭梢宰允〉哪芰Γ捶瓷洹T诤唵喂S模式中,根據(jù)傳遞的參數(shù)來返回不同的類的實例簡單工廠模式又稱為靜態(tài)工廠方法模式。也就是簡單工廠模式工廠工廠類。PHP高級特性-反射以及工廠設計模式的結(jié)合使用 [結(jié)合 Laravel-Admin 代碼實例講解]利用反射來實現(xiàn)工廠模式的生產(chǎn)而無需創(chuàng)建特定的工廠類本文地址http://janrs.com/?p=833轉(zhuǎn)載無需經(jīng)過作者本人授權(quán)轉(zhuǎn)載...
摘要:判斷是否存在構(gòu)造函數(shù),不存在直接實例化,存在則通過來獲取輸入函數(shù),并有相應的方法解決依賴參數(shù)問題,實現(xiàn)依賴注入。 Laravel 框架關鍵技術解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數(shù)的添加 服務器實例化與服務注冊 路由加載 請求實例化與路由分發(fā) 相應生成與發(fā)送 其中,自動加載函數(shù)用于包含引用文件,改文件是composer...
摘要:簡介是才有的新功能,它是用來導出或提取出關于類方法屬性參數(shù)等的詳細信息,包括注釋。 簡介 PHP Reflection API是PHP5才有的新功能,它是用來導出或提取出關于類、方法、屬性、參數(shù)等的詳細信息,包括注釋。 class Reflection { } interface Reflector { } class ReflectionException extends Exce...
摘要:發(fā)現(xiàn)大量的使用了反射機制。下面就來簡單看看一些反射的應用獲得反射下面我們來通過這個反射來得到的私有屬性得到結(jié)果得到這樣我們就可以很輕松的獲得的私有屬性了。最后通過執(zhí)行該方法反射還有很多可用的方法,這里就不一一說了。 這幾天在看laravel框架的核心代碼。發(fā)現(xiàn)大量的使用了反射機制。下面就來簡單看看一些反射的應用 class A { private $_foo = this i...
閱讀 1241·2021-11-08 13:25
閱讀 1440·2021-10-13 09:40
閱讀 2774·2021-09-28 09:35
閱讀 736·2021-09-23 11:54
閱讀 1123·2021-09-02 15:11
閱讀 2431·2019-08-30 13:18
閱讀 1668·2019-08-30 12:51
閱讀 2686·2019-08-29 18:39