andel 发表于 2019-12-22 14:04:37

整合PHP-DI,让CI用上依赖注入

本帖最后由 andel 于 2019-12-22 14:04 编辑

最近我捣鼓了一下CI3,在不改动框架核心文件和不改变框架原有功能的前提下,把PHP-DI整合进来了,让在CI3.x上构建的项目可以使用依赖注入。


class MY_Hooks extends CI_Hooks
{
    public function __construct()
    {
      parent::__construct();
    }

    /**
   * The instance of DI ContainerBuilder
   * @var 用于存放容器建造器实例(单例)
   */
    private static $di_container_builder;

    /**
   * The instance of CI_Controller
   * @var CodeIgniter 对象(单例)
   */
    private static $ci;

    /**
   * Call Hook
   *
   *
   * @uses      CI_Hooks::_run_hook()
   *
   * @param      string      $which      Hook name
   * @return      bool      TRUE on success or FALSE on failure
   */
    public function call_hook($which = '')
    {
      if ($which === 'post_controller_constructor')
      {
            // 由于实现依赖注入后,为了实现松耦合,控制器不再继承CI_Controller,但为了仍可以访问 CodeIgniter资源,需要实例化CI_Controller类
            if (self::$ci == NULL) {
                self::$ci = new CI_Controller;
            }
            // 实例化构建器
            if (self::$di_container_builder == NULL) {
                self::$di_container_builder = new DI\ContainerBuilder;
            }                        
            // 构建DI容器
            $container = self::$di_container_builder->addDefinitions(APPPATH.'config/di.php')->build();
            // 重载 Controller实例$CI,改由DI容器生成,从而在所有控制器中实现依赖注入
            global $CI, $class;                              
            $CI = $container->get($class);
      }
                /**
               * 以下与父类call_hook方法一致
               */
                if ( ! $this->enabled OR ! isset($this->hooks[$which]))
                {
                        return FALSE;
                }

                if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
                {
                        foreach ($this->hooks[$which] as $val)
                        {
                              $this->_run_hook($val);
                        }
                }
                else
                {
                        $this->_run_hook($this->hooks[$which]);
                }

                return TRUE;
    }

}



源码获取:https://github.com/Xandel/DI_CI
Demo演示:http://andel.xlphp.net
有兴趣的朋友可以参考Demo,通过以下几个步骤整合CI和PHP-DI:1. composer install 或 composer update(composer.json的设置请参考Demo的composer.json文件);2. 把框架核心扩展文件MY_Hooks.php安装到 application/core 路径下;3. 把DI容器配置文件di.php安装到 application/config 路径下。这样就可以了,您可以在控制器里使用依赖注入了。控制器的依赖以及依赖的依赖均由DI容器注入,实现了高度松耦合。要注意的一点是,不能在控制器的构造函数里使用参数type-hint的方式注入依赖,建议使用属性注入。关于DI容器的使用方法,欢迎访问PHP-DI官网获取更多信息。以下这篇文章有更详细的解析:https://zhuanlan.zhihu.com/p/98644060欢迎讨论。

zh7908 发表于 2020-2-21 20:21:48

woc对你的如滔滔江水绵延不绝

zhaohua0317 发表于 2020-2-24 18:03:28

大神就是大神

272021899 发表于 2020-4-27 17:21:52

啥时候整一个ci4版本的
页: [1]
查看完整版本: 整合PHP-DI,让CI用上依赖注入