本帖最后由 andel 于 2019-12-22 14:04 编辑
最近我捣鼓了一下CI3,在不改动框架核心文件和不改变框架原有功能的前提下,把PHP-DI整合进来了,让在CI3.x上构建的项目可以使用依赖注入。
PHP复制代码
class MY_Hooks extends CI_Hooks
{
public function __construct ()
{
parent ::__construct ();
}
/**
* The instance of DI ContainerBuilder
* @var [DI\ContainerBuilder] 用于存放容器建造器实例(单例)
*/
private static $di_container_builder;
/**
* The instance of CI_Controller
* @var [CI_Controller] 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 欢迎讨论。
|