摘要:說明的核心容器有一部分就是利用反射來實現依賴注入時類的實例化。這是一個簡化版示例。
說明
Laravel的核心容器,有一部分就是利用反射來實現依賴注入時類的實例化。這是一個簡化版示例。代碼 測試用的類
/** * 坦克標準: 必須能開火 */ interface Tank { public function fire(); } /** * 59坦克,使用100毫米炮 */ class Tank59 implements Tank { private $gun = 100; public function fire() { echo $this->gun . PHP_EOL; } } /** * 59加強版,可以使用100毫米炮或120毫米炮,默認120毫米炮 */ class Tank59Plus implements Tank { private $gun; public function __construct($gun = 120) { if($gun != 100 && $gun != 120) { throw new Exception("口徑不合適"); } $this->gun = $gun; } public function fire() { echo $this->gun . PHP_EOL; } } /** * 59超級版,可以使用任意口徑的炮,必須提供一門火炮 */ class Tank59Super implements Tank { private $gun; public function __construct($gun) { $this->gun = $gun; } public function fire() { echo $this->gun . PHP_EOL; } } /** * 坦克營,裝備59和59加強版,必須提供59和59加強版 */ class TankArmy implements Tank { private $tank59; private $tank59Plus; public function __construct(Tank59 $tank59, Tank59Plus $tank59Plus) { $this->tank59 = $tank59; $this->tank59Plus = $tank59Plus; } public function fire() { echo $this->tank59->fire(); echo $this->tank59Plus->fire(); } }容器
/** * 兵工廠 */ class Factory { /** * 創建實體對象 */ public static function build($blueprint) { //反射,獲取類細節 $reflector = new ReflectionClass($blueprint); //無法創建的類,比如接口,抽象類 if(!$reflector->isInstantiable()) { throw new Exception("提供的不是坦克圖紙,不能制造"); } //獲取類的構造方法 $constructor = $reflector->getConstructor(); if (is_null($constructor)) { //沒有構造方法,直接new return new $blueprint; } $parameters = []; //獲取構造方法依賴的參數 $dependencies = $constructor->getParameters(); foreach ($dependencies as $dependency) { if(is_null($dependency->getClass())) { //依賴參數不是對象 //如果構造方法參數有默認值,獲取默認值 if($dependency->isDefaultValueAvailable()) { $parameters[] = $dependency->getDefaultValue(); } } else { //依賴參數是對象,遞歸創建 $parameters[] = self::build($dependency->getClass()->name); } } if(!$parameters) { //有構造方法且構造方法有參數,卻沒有可以提供的實參,無法創建 throw new Exception("坦克缺少必要的零件,不能制造"); } else { //使用反射提供的方法創建對象,傳入參數 return $reflector->newInstanceArgs($parameters); } } }測試 Tank
$tank = Factory::build(Tank::class); echo $tank->fire(); //輸出 //PHP Fatal error: Uncaught Exception: 提供的不是坦克圖紙,不能制造Tank59
$tank = Factory::build(Tank59::class); echo $tank->fire(); //輸出 //100Tank59Plus
$tank = Factory::build(Tank59Plus::class); echo $tank->fire(); //輸出 //120Tank59Super
$tank = Factory::build(Tank59Super::class); echo $tank->fire(); //輸出 //Fatal error: Uncaught Exception: 坦克缺少必要的零件,不能制造TankArmy
$tank = Factory::build(TankArmy::class); echo $tank->fire(); //輸出 //100 //120
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28627.html
摘要:本章講解反射類的使用及對反射的使用。各位很清楚,方法用于解析類,所有方法的實現一定是在引用的文件內。致謝感謝你看到這里,本篇文章源碼解析靠個人理解。 showImg(https://segmentfault.com/img/bVbhjvY?w=600&h=296); 前言 PHP的反射類與實例化對象作用相反,實例化是調用封裝類中的方法、成員,而反射類則是拆封類中的所有方法、成員變量,并...
摘要:控制反轉容器控制反轉使依賴注入變得更加便捷。有瑕疵控制反轉容器是實現的控制翻轉容器的一種替代方案。容器的獨立使用即使沒有使用框架,我們仍然可以在項目中使用安裝組件來使用的控制反轉容器。在沒有給定任何信息的情況下,容器是無法實例化相關依賴的。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味...
摘要:判斷是否存在構造函數,不存在直接實例化,存在則通過來獲取輸入函數,并有相應的方法解決依賴參數問題,實現依賴注入。 Laravel 框架關鍵技術解析·讀書筆記(一) 第一章 入口文件 請求訪問的入口文件,主要完成幾部分工作,分別是: 自動加載函數的添加 服務器實例化與服務注冊 路由加載 請求實例化與路由分發 相應生成與發送 其中,自動加載函數用于包含引用文件,改文件是composer...
在 Laravel 的控制器的構造方法或者成員方法,都可以通過類型約束的方式使用依賴注入,如: public function store(Request $request) { //TODO } 這里 $request 參數就使用了類型約束,Request 是類型約束的類型,它是一個類:IlluminateHttpRequest. 本文研究 Laravel 的依賴注入原理,為什么這樣定義...
摘要:反射在每個面向對象的編程語言中都存在,它的主要目的就是在運行時分析類或者對象的狀態,導出或提取出關于類方法屬性參數等的詳細信息,包括注釋。反射是操縱面向對象范型中元模型的,可用于構建復雜,可擴展的應用。 反射在每個面向對象的編程語言中都存在,它的主要目的就是在運行時分析類或者對象的狀態,導出或提取出關于類、方法、屬性、參數等的詳細信息,包括注釋。 反射是操縱面向對象范型中元模型的 AP...
閱讀 1784·2023-04-25 15:51
閱讀 2497·2021-10-13 09:40
閱讀 2134·2021-09-23 11:22
閱讀 3244·2019-08-30 14:16
閱讀 2652·2019-08-26 13:35
閱讀 1847·2019-08-26 13:31
閱讀 874·2019-08-26 11:39
閱讀 2732·2019-08-26 10:33