1. 程式人生 > 其它 >[PHP] 理解依賴注入容器-自動注入

[PHP] 理解依賴注入容器-自動注入

原文地址:

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");