当前位置 : 主页 > 网络编程 > PHP >

ioc容器demo

来源:互联网 收集:自由互联 发布时间:2021-06-28
Container /** * 容器 * Class Container * @Auth: kingofzihua */class Container{ /** * 所有的绑定的类和实例 * @Auth: kingofzihua * @var array */ protected $bindings = []; /** * 绑定容器 * @Auth: kingofzihua * @param $abstract 抽
Container
/**
 * 容器
 * Class Container
 * @Auth: kingofzihua
 */
class Container
{
    /**
     * 所有的绑定的类和实例
     * @Auth: kingofzihua
     * @var array
     */
    protected $bindings = [];

    /**
     * 绑定容器
     * @Auth: kingofzihua
     * @param $abstract 抽象类
     * @param null $concrete 实际的类
     * @param bool $shared
     */
    public function bind($abstract, $concrete = null, $shared = false)
    {
        if (!$concrete instanceof Closure) {
            $concrete = $this->getClosure($abstract, $concrete);
        }
        $this->bindings[$abstract] = compact('concrete', 'shared');
    }

    /**
     * 获取闭包函数
     * @Auth: kingofzihua
     * @param $abstract
     * @param $concrete
     * @return Closure
     */
    public function getClosure($abstract, $concrete)
    {
        return function ($c, $parameters = []) use ($abstract, $concrete) {
            $method = ($abstract == $concrete) ? 'build' : 'make';

            return $c->$method($concrete, $parameters);
        };
    }

    /**
     * 取出指定的类[实例化指定的类]
     * @Auth: kingofzihua
     * @param $abstract
     * @param array $parameters
     * @return mixed|object|string
     */
    public function make($abstract, $parameters = [])
    {
        $concrete = $this->getConcrete($abstract); //取出

        if ($this->isBuildable($concrete, $abstract)) { //判断是否是可以 实例化的
            $object = $this->build($concrete, $parameters); //构造
        } else {
            $object = $this->make($concrete, $parameters);
        }
        return $object;
    }

    /**
     * 判断是否可以实例化
     * @Auth: kingofzihua
     * @param $concrete
     * @param $abstract
     * @return bool
     */
    protected function isBuildable($concrete, $abstract)
    {
        return $concrete === $abstract || $concrete instanceof Closure;
    }

    /**
     * 通过接口类获取类的实例
     * @Auth: kingofzihua
     * @param $abstract
     * @return mixed
     */
    protected function getConcrete($abstract)
    {
        if (!isset($this->bindings[$abstract])) {
            return $abstract;
        }
        return $this->bindings[$abstract]['concrete'];
    }

    /**
     * 构建类
     * @desc 实例化指定的类 依赖注入
     * @Auth: kingofzihua
     * @param $concrete
     * @param array $parameters
     * @return mixed|object|string
     */
    public function build($concrete, $parameters = [])
    {

        if ($concrete instanceof Closure) { //如果是闭包函数 那么调用当前闭包 返回 绑定的类名
            return $concrete($this, $parameters);
        }

        $reflector = new ReflectionClass($concrete); //反射获取类 Message

        if (!$reflector->isInstantiable()) { //判断是否是可以实例化的
            return $message = "Target [$concrete] is not instantiable.";
        }

        $constructor = $reflector->getConstructor(); //获取构造方法

        if (is_null($constructor)) { //如果没有构造方法 直接返回实例化的对象
            return new $concrete;
        }

        $dependencies = $constructor->getParameters(); //获取构造方法的参数

        $instances = $this->getDependencies($dependencies, $parameters); //获取实例


        return $reflector->newInstanceArgs($instances);
    }

    /**
     * 获取依赖注入的类
     * @Auth: kingofzihua
     * @param $parameters 构造方法的 所需要的
     * @param array $primitives 额外参数
     * @return array
     */
    protected function getDependencies($parameters, array $primitives = [])
    {
        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();

            if (array_key_exists($parameter->name, $primitives)) {
                $dependencies[] = $primitives[$parameter->name];
            } else if (is_null($dependency)) { //
                $dependencies[] = NULL;
            } else {
                $dependencies[] = $this->resolveClass($parameter);
            }

        }
        return (array)$dependencies;
    }

    /**
     * 获取类的实例
     * @Auth: kingofzihua
     * @param ReflectionParameter $parameter
     * @return mixed|object|string
     */
    protected function resolveClass(ReflectionParameter $parameter)
    {
        return $this->make($parameter->getClass()->name);
    }
}
sendMessage
/**
 * 通知
 * @Auth: kingofzihua
 * Interface Notify
 */
interface Notify
{

    /**
     * 发送通知
     * @Auth: kingofzihua
     * @return mixed
     */
    public function send();
}

/**
 * 短信
 * Class SMS
 * @Auth: kingofzihua
 */
class SMS implements Notify
{
    /**
     * 发送通知
     * @Auth: kingofzihua
     * @return mixed
     */
    public function send()
    {
        echo 'SMS send';
    }
}

/**
 * Mail
 * Class SMS
 * @Auth: kingofzihua
 */
class Mail implements Notify
{
    /**
     * 发送通知
     * @Auth: kingofzihua
     * @return mixed
     */
    public function send()
    {
        echo 'Mail send';
    }
}

/**
 * 发送
 * Class Push
 * @Auth: kingofzihua
 */
class Push implements Notify
{
    /**
     * 发送
     * @Auth: kingofzihua
     */
    public function send()
    {
        echo 'Push send';
    }
}

/**
 * 消息
 * Class Message
 * @Auth: kingofzihua
 */
class Message
{
    /**
     * @Auth: kingofzihua
     * @var Notify
     */
    protected $notifyTool;
    /**
     * @Auth: kingofzihua
     * @var array
     */
    protected $config;

    /**
     * @Auth: kingofzihua
     * Message constructor.
     * @param Notify $notify
     * @param array $parameters
     */
    public function __construct(Notify $notify, $parameters = [])
    {
        $this->notifyTool = $notify;
        $this->config = $parameters;
    }

    /**
     * 发送消息
     * @Auth: kingofzihua
     */
    public function sendMessage()
    {
        dump($this->notifyTool);
        $this->notifyTool->send();
    }
}

$app = new Container();
$app->bind('Notify', 'Sms');
$app->bind('message', 'Message');
$msg = $app->make('message', ['parameters' => '额外参数']);
$msg->sendMessage();
die();
网友评论