PHP教程

php实现IoC容器

本文主要是介绍php实现IoC容器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

DI:Dependency Injection,依赖注入,是指在程序运行期间,如果依赖于其它的对象时,不在
代码中创建该类对象,而是由外部容器创建后再传递给程序(即由容器动态的将某些依赖关系注入到组件中)
 IoC:Inversion of Control,控制反转,是面向对象编程中的一种设计原则,它的目的是帮助我们设计出松耦合、更灵活、易扩展的程序代码。IoC意味着把你设计好的对象交给容器控制,而不是传统的由程序对象内部直接控制。IoC容器管理所有轻量级的扩展组件对象,提供 包括组件的生命周期管理、配置和组装等服务。如果把程序代码对其它依赖对象的控制权(主动实例化和调用)看作正向控制,那么这种把依赖对象的控制权交给外部容器,然后向IoC容器来申请这些资源,则即为控制反转。

IoC中最常见的方式是“依赖注入”(Dependency Injection),还有一种方式叫“依赖查找”(Dependency Lookup)。

对IoC容器的实践:

<?php

class IoC {
    // 注册服务集合
    public $services = [];

    /**
     * 注册服务
     * @param $class
     * @param $generator
     */
    public function bind($class, $generator)
    {
        if ($generator instanceof Closure) {
            $this->services[$class] = $generator;
        } else {
            $this->services[$class] = function () use ($generator) {
                return $this->build($generator);
            };
        }
    }

    /**
     * 获取服务对象实例
     * @param $class
     * @return object|null
     */
    public function make($class)
    {
        if (isset($this->services[$class])) {
            $new = $this->services[$class];
        } else {
            $new = function () use ($class) {
                return $this->build($class);
            };
        }
        return $new();
    }

    /**
     * 通过反射构建服务实现
     * @param $class
     * @param array $params
     * @return object|null
     */
    public function build($class, $params = [])
    {
        try {
            $reflection = new ReflectionClass($class);
            // 判断类是否可实例化
            if (!$reflection->isInstantiable()) {
                return null;
            }
            // 获取类构造器
            $constructor = $reflection->getConstructor();
            // 判断构造方法是否为null,为null时直接返回实例
            if (is_null($constructor)) {
                return new $class;
            }
            // 获取构造器参数列表
            $parameters = $constructor->getParameters();
            // 判断构造方法参数列表是否为空,为空时直接返回实例
            if (empty($parameters)) {
                return new $class;
            }
            $dependencies = [];
            // 检查注入的依赖
            foreach ($parameters as $parameter) {
                // 获取参数声明的类型
                $dependencyClass = $parameter->getClass();
                if (is_null($dependencyClass)) {
                    $dependencies[] = null;
                } else {
                    $dependencies[] = $this->make($dependencyClass->getName());
                }
            }
            return $reflection->newInstanceArgs($dependencies);
        } catch (\Exception $e) {

        }
    }

}

class User {

    public $userAddress;

    public function __construct(UserAddress $userAddress)
    {
        // 主动实例化依赖对象
//        $this->userAddress = new UserAddress();
        // 外部注入
        $this->userAddress = $userAddress;
    }

    public function showUserAddress()
    {
        $this->userAddress->getUserAddress();
    }
}

class UserAddress {

    public function getUserAddress()
    {
        echo 'shanghai';
    }

}

$ioc = new IoC();
$ioc->bind('User', 'User');
$user = $ioc->make('User');
$user->showUserAddress();

基于IoC,我们可以继续扩展,增加单例、上下文绑定等设计。

这篇关于php实现IoC容器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!