[PHP] 理解依賴注入容器-自動注入
阿新 • • 發佈:2021-06-18
原文地址:
PHP反射機制實現自動依賴注入 - 知乎 (zhihu.com)
利用反射類獲取類的物件,當有依賴其他類的時候,利用反射類獲取到被依賴的物件,自動注入進來
A依賴 B ===> B依賴C
class C{ public function __construct() { } public function doC(){ echo "C"; } } class B{ protected $c; public function __construct(C $c) { $this->c=$c; } }class A{ protected $b; public function __construct(B $b) { $this->b=$b; } public function doC(C $c){ $c->doC(); } }
使用反射類通過類名獲取到被依賴的物件,直接通過建構函式或者類方法注入
/** * * 工具類,使用該類來實現自動依賴注入。 * */ class Ioc { // 獲得類的物件例項 public static function getInstance($className) { $paramArr= self::getMethodParams($className); return (new ReflectionClass($className))->newInstanceArgs($paramArr); } /** * 執行類的方法 * @param [type] $className [類名] * @param [type] $methodName [方法名稱] * @param [type] $params [額外的引數] * @return [type] [description]*/ public static function make($className, $methodName, $params = []) { // 獲取類的例項 $instance = self::getInstance($className); // 獲取該方法所需要依賴注入的引數 $paramArr = self::getMethodParams($className, $methodName); return $instance->{$methodName}(...array_merge($paramArr, $params)); } /** * 獲得類的方法引數,只獲得有型別的引數 * @param [type] $className [description] * @param [type] $methodsName [description] * @return [type] [description] */ protected static function getMethodParams($className, $methodsName = '__construct') { // 通過反射獲得該類 $class = new ReflectionClass($className); $paramArr = []; // 記錄引數,和引數型別 // 判斷該類是否有建構函式 if ($class->hasMethod($methodsName)) { // 獲得建構函式 $construct = $class->getMethod($methodsName); // 判斷建構函式是否有引數 $params = $construct->getParameters(); if (count($params) > 0) { // 判斷引數型別 foreach ($params as $key => $param) { if ($paramClass = $param->getClass()) { // 獲得引數型別名稱 $paramClassName = $paramClass->getName(); // 獲得引數型別 $args = self::getMethodParams($paramClassName); $paramArr[] = (new ReflectionClass($paramClass->getName()))->newInstanceArgs($args); } } } } return $paramArr; } }
$a=Ioc::getInstance("A"); var_dump($a); Ioc::make("A","doC");