PHP的反射類與實例化對象作用相反,實例化是調用封裝類中的方法、成員,而反射類則是拆封類中的所有方法、成員變量,并包括私有方法等。就如“解刨”一樣,我們可以調用任何關鍵字修飾的方法、成員。當然在正常業(yè)務中是建議不使用,比較反射類已經摒棄了封裝的概念。
本章講解反射類的使用及Laravel對反射的使用。
反射反射類是PHP內部類,無需加載即可使用,你可以通過實例化 ReflectionClass 類去使用它。
方法這里列舉下PHP反射類常用的方法
方法名注釋ReflectionClass::getConstant獲取定義過的一個常量ReflectionClass::getConstants獲取一組常量ReflectionClass::getConstructor獲取類的html' target='_blank'>構造函數ReflectionClass::getDefaultProperties獲取默認屬性ReflectionClass::getDocComment獲取文檔注釋ReflectionClass::getEndLine獲取最后一行的行數ReflectionClass::getFileName獲取定義類的文件名ReflectionClass::getInterfaceNames獲取接口(interface)名稱ReflectionClass::getMethods獲取方法的數組ReflectionClass::getModifiers獲取類的修飾符ReflectionClass::getName獲取類名ReflectionClass::getNamespaceName獲取命名空間的名稱ReflectionClass::getParentClass獲取父類等等等等.... 所有關于類的方法、屬性及其繼承的父類、實現的接口都可以查詢到。
詳細文檔請參考網址
?php namespace A/B; class Foo { } $function = new /ReflectionClass( stdClass var_dump($function- inNamespace()); var_dump($function- getName()); var_dump($function- getNamespaceName()); var_dump($function- getShortName()); $function = new /ReflectionClass( A//B//Foo var_dump($function- inNamespace()); var_dump($function- getName()); var_dump($function- getNamespaceName()); var_dump($function- getShortName());?
輸出結果
bool(false)string(8) stdClass string(0) string(8) stdClass bool(true)string(7) A/B/Foo string(3) A/B string(3) FooLaravel
Laravel在實現服務容器加載時使用了反射類。現在我們開啟“解刨”模式
入口文件index.php$app = require_once __DIR__. /../bootstrap/app.php |--------------------------------------------------------------------------| Run The Application|--------------------------------------------------------------------------| Once we have the application, we can handle the incoming request| through the kernel, and send the associated response back to| the client s browser allowing them to enjoy the creative| and wonderful application we have prepared for them.$kernel = $app- make(Illuminate/Contracts/Http/Kernel::class);$response = $kernel- handle( $request = Illuminate/Http/Request::capture()$response- send();$kernel- terminate($request, $response);
是引用語句發(fā)生的下一行調用了make方法。各位很清楚,make方法用于解析類,所有make方法的實現一定是在引用的文件內。
bootstrap/app.php$app = new Illuminate/Foundation/Application( realpath(__DIR__. /../ ));
laravel開始加載它的核心類,所有的實現從 Illuminate/Foundation/Application 開始。
Illuminate/Foundation/Applicationpublic function make($abstract, array $parameters = []) $abstract = $this- getAlias($abstract); if (isset($this- deferredServices[$abstract]) ! isset($this- instances[$abstract])) { $this- loadDeferredProvider($abstract); return parent::make($abstract, $parameters);}
在核心類中你可能準確的查找到make方法的存在,它加載了服務提供者隨后調用了父類的方法make,要知道作為獨立的模塊 “服務容器”是絕對不能寫在核心類的。懂點設計模式的都很清楚。
Illuminate/Container/Container以 $api = $this- app- make( HelpSpot/API ,[ id = 為例來講解
// 真正的make方法,它直接調用了resolve繼續(xù)去實現make的功能// $abstract = HelpSpot/API public function make($abstract, array $parameters = []) // $abstract = HelpSpot/API return $this- resolve($abstract, $parameters);protected function resolve($abstract, $parameters = []) // 判斷是否可以合理反射 // $abstract = HelpSpot/API if ($this- isBuildable($concrete, $abstract)) { // 實例化具體實例 (實際并不是實例化,而是通過反射“解刨”了) $object = $this- build($concrete); } else { $object = $this- make($concrete);public function build($concrete) // $concrete = HelpSpot/API if ($concrete instanceof Closure) { return $concrete($this, $this- getLastParameterOverride()); // 實例化反射類 $reflector = new ReflectionClass($concrete); // 檢查類是否可實例化 if (! $reflector- isInstantiable()) { return $this- notInstantiable($concrete); $this- buildStack[] = $concrete; // 獲取類的構造函數 $constructor = $reflector- getConstructor(); if (is_null($constructor)) { array_pop($this- buildStack); return new $concrete; $dependencies = $constructor- getParameters(); $instances = $this- resolveDependencies( $dependencies array_pop($this- buildStack); // 從給出的參數創(chuàng)建一個新的類實例。 return $reflector- newInstanceArgs($instances);}
可見一個服務容器就加載成功了。
以上就是php反射類的使用及Laravel對反射的使用介紹的詳細內容,PHP教程
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答