由于 我的框架(框架 请看上一篇)使用了两套数据源
一套是http的接口请求方式,一套是直接链接 mysql的方式
故而 两套方式,要是想通过配置化的方式就能够实现 数据源的切换,
进而想到了 依赖注入的方式实现该功能
最早接触 IOC容器 是由于之前做 .net的时候,那时候听别人讲这些专业名词 觉得挺高大上的,不过不知道它的优势在哪。
后面深入了解了之后,由于 注入的解耦的特性,以及 它的高扩展性 确实非常高深。
就像 我们目前做的一个系统,由于之前用的是mysql直接连的数据源,到现在 数据量庞大的时候,发现了它的数据读写瓶颈,可是也很无奈呀。
想要将数据源移植到 分布式的微服务架构中, 前端上只做一些简单的php处理。可是由于之前的代码扩展性很差,工程量 很庞大,只能开始重构系统了。
非常痛苦。
下面通过user 的 数据添加功能进行操作
依赖注入
构造注入
通过构造方法进行对象注入
public class UserModels { private Db $db; // 注入 public function UserModels($server) { $this->db=$server; } public function add($data) { $this->db->add($data); } } public class UserController { public addUser() { $user=array(); Db mysql=new Mysql(); UserModels usermodels=new UserModels(mysql); usermodels->add($user); } }
属性注入
通过setter 方法进行对象注入
public class UserModels { private Db $db; // 注入 public function setDb($server) { $this->db=$server; } public function add($data) { $this->db->add($data); } } public class UserController { public addUser() { $user=array(); Db mysql=new Mysql(); UserModels usermodels=new UserModels(); usermodels->setDb(mysql); usermodels->add($user); } }
属性注入的话,就是当你想要注入该对象就注入 不用在我们的对象构造的时候就注入其中,会耦合性更低。
否则,如果我们一个类 使用了多个对象,那岂不是 构造方法的参数 一堆堆的。。
接口注入
接口注入的方式就是通过一个接口进行对象注入
public interface Models { public function initDb($server); } public class UserModels implements Models { private Db $db; // 注入 public function initDb($server) { $this->db=$server; } public function add($data) { $this->db->add($data); } } public class UserController { public addUser() { $user=array(); Db mysql=new Mysql(); UserModels usermodels=new UserModels(); usermodels->initDb(mysql); usermodels->add($user); } }
发现,这些注入方式的代码 还是不好写,麻烦,想通过配置的方式,底层实现,然后在具体业务上不需要关心我的数据源。。然后 想到了IOC容器,来实现 自动的依赖注入
java 的spring 框架就是用来做这个事情的。可是 我是php 啊。。怎么办咧。。想要自己实现一套 类似的东西。
不想用xml 就用 配置的数组吧。
先添加一个配置文件
<?php namespace Config; /** * IOC容器配置 * @author */ class Ucontainer { // public static $db = array( 'UserModels' => 'Db',// 或者指向 Api ); }
然后添加一个
Ucontainer.php类 来做注入
<?php namespace Lib; class UContainer{ /** *@intro 通过配置 获取 数据源对象 *@author kinmos *@time *@param *@return */ public static function getDbInstanse($models) { $dbContainer=ConfigUcontainer::$db; if(isset($dbContainer[$models])&&!empty($dbContainer[$models])) { $source=str_replace('Models','',$models); $classname = "Http\Models\".$dbContainer[$models]."\".$source; return new $classname; } } }
这样 ,在我们的数据层 。定义的Models 文件夹中添加一个UserModels 文件
UserModels.php
<?php namespace HttpModels; use LibUContainer; class UserModels { private static $classname='UserModels'; // 获取用户列表 public static function userList($params=array()){ $data=UContainer::getDbInstanse(self::$classname)->userList(); return $data; } }
这样在我们的Models 里面的Db 和 Api 文件夹中各自添加各自方式的数据源
Api.User.php
<?php namespace HttpModelsApi; class User { public function userList($apiReqData = array()) { $result = array(); //组装API请求的数据 $apiName = 'User.userList'; //接口的名称 //请求API,得到返回的数据(数组格式) $resultEntity = httpApiGetData($apiName, $apiReqData); if ($resultEntity['code'] == 200) { $result = $resultEntity['data']; } return $result; } }
Db.User.php
<?php namespace HttpModelsDb; use LibDbTable; /** * */ class User extends DbTable { protected $_name = 'user'; protected $_primary = 'id'; protected $_db = 'default'; /* * 构造函数 */ public function __construct() { } public function userList($params=array()) { // 查询所有数据 $list=$this->getList('1=1'); return $list; } }
这样 一个整个简单的容器就搭建起来了。然后在使用上就简单了。
namespace HttpControllersDemo; use HttpModelsUserModels; use HttpControllersActionController; class IndexController extends ActionController { public function index() { $data=UserModels::userList(); print_r($data);die; } }
使用上,只需要调用 Models层的数据,就可以了。业务上不需要关系到底 从那个数据源中取数据,
同样的道理,如果 需要 添加sqlserver的数据源,同样的方式 添加一个sqlserver的服务就可以加以注入