Ioc实现的基本机制

<?php

interface KeyBoard{
    public function make();
}

interface Mouse{
    public function make();
}

class MechanicalKeyboard implements KeyBoard
{
    public function make(){
        echo '机械键盘正在work';
    }
}

class CommonKeyboard implements KeyBoard
{
    public function make(){
        echo '普通键盘正在work';
    }
}

class CommonMouse implements Mouse
{
    public function make(){
        echo '普通鼠标正在work';
    }
}


class Computer
{
    protected $keyBoard;

    protected $mouse;

    public function __construct(KeyBoard $keyBoard,Mouse $mouse)
    {
        $this->keyBoard = $keyBoard;

        $this->keyBoard->make();

        $this->mouse = $mouse;

        $this->mouse->make();
    }
}

class Container
{
    private $binds;

    //将接口和类名保存到binds中
    public function bind($contract,$concrete)
    {
        $this->binds[$contract] = $concrete;
    }

    //获取到指定方法的注入参数,默认方法是采用__construct进行注入
    public function methodBindParams($className)
    {
        $reflect = new Reflect($className,'__construct');

        return $reflect->bindParamsToMethod();
    }

    //实例化类
    public function make($className)
    {
        //获取需要实例化类所需要的必要参数
        $methodBindParams = $this->methodBindParams($className);

        //实例化类反射类
        $reflect = new Reflect($className,'__construct');

        //实例化类,插入实例化所需要的参数和参数接口对应的类
        return $reflect->make($this->binds,$methodBindParams);
    }
}

class Reflect
{
    private $className;

    private $methodName;

    public function __construct($className,$methodName)
    {
        $this->className = $className;

        $this->methodName = $methodName;
    }

    public function bindParamsToMethod()
    {
        $params = [];

        //获取到类的方法信息
        $method = new ReflectionMethod($this->className,$this->methodName);

        //将类方法参数信息保存到params中
        foreach ($method->getParameters() as $param){
            $params[] = [
                //参数名称
                $param->name,
                //参数是哪个类型
                $param->getClass()->name
            ];
        }

        //返回这个类--》方法的参数
        return [$this->className => $params];
    }

    public function make($bind,$methodBindParams)
    {
        $args = [];

        //遍历类-》参数列表
        foreach ($methodBindParams as $className => $params){
            //遍历参数列表
            foreach ($params as $param){
                //获取到参数名和参数类型(是哪个接口)
                list($paramName,$paramType) = $param;

                //实例化对应接口的实现的类
                $paramName = new $bind[$paramType]();

                //将实例化后的类放到args列表中
                array_push($args,$paramName);
            }
        }

        //实例化反射
        $reflectionClass = new ReflectionClass($this->className);

        //从给定参数生成一个实例
        return $reflectionClass->newInstanceArgs($args);
    }
}

$container = new Container();

$container->bind('KeyBoard','CommonKeyBoard');
$container->bind('Mouse','CommonMouse');

$container->make('Computer');
原文地址:https://www.cnblogs.com/ywjcqq/p/14078684.html