首页 > 开发 > PHP > 正文

CodeIgniter读写分离实现方法详解

2024-05-04 22:32:46
字体:
来源:转载
供稿:网友

本文实例讲述了CodeIgniter读写分离实现方法。分享给大家供大家参考,具体如下:

当前服务器只做了主从,未配置读写分离,读写分离的功能就只有交给程序来实现,这里主要谈谈Codeigniter怎么实现读写分离,并且需要满足以下两点:

1、读写分离对开发应该透明。

网上有方案通过手动load多个DB来实现读写分离,这样的分离跟业务关联太紧,增加了开发难度也不利于维护,我们要做的是默认读重库,写则写主库,读写分离对开发者透明

2、配置简单。

保留现有的配置方式,通过增加一个数组来配置读写分离,不影响原有使用方式。

思路

1、要实现读写分离最简单的思路就是在最终执行查询的地方根据查询语句判断是插入主库还是读取从库,所以需要找到该函数。

2、应该只连接一次数据库,下次操作该链接应当可复用。也就是连一次重库后所有的读操作都可用,不需再次连接,主库同理。所以我们可以将链接放在CI超级对象中。

3、主从的判断是根据最终执行的SQL语句来判断的,所以数据库配置中的自动链接autoinit参数就不用设置为true了,如果默认连接了而又不需要操作该库就浪费资源了。

4、模型中可以使用$this->db来直接操作查询,不需要其他调整。

5、不直接修改system下的文件

实现读写分离

CI的DB类固定为读取system下的文件,我们可以通过适当的重写来实现。首先是Loader.php,其中的database方法用来加载数据库对象,固定引用了system/database/DB.php文件,我们判断下是否存在自定义DB.php文件,存在则引入。

重写Loader.php

public function database($params = '', $return = FALSE, $active_record = NULL){  $CI =& get_instance();  if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)) {    return FALSE;  }  if(file_exists(APPPATH.'core/database/DB.php')) {    require_once(APPPATH.'core/database/DB.php');  } else {    require_once(BASEPATH.'database/DB.php');  }  if ($return === TRUE) {    return DB($params, $active_record);  }  $CI->db = '';  $CI->db =& DB($params, $active_record);}/* End of file MY_Loader.php *//* Location: ./application/core/MY_Loader.php */

接着我们在application/core下创建database/DB.php,该文件只有一个DB方法,用来读取配置文件并进行初始化工作。同样有两处地方需要重写下:

重写DB.php

//DB_driver.php为所有驱动方式的父类,最终执行查询的方法在该文件中//第一处修改为判断自定义的DB_driver.php是否存在,存在则引入if(file_exists(APPPATH.'core/database/DB_driver.php')) {  require_once(APPPATH.'core/database/DB_driver.php');} else {  require_once(BASEPATH.'database/DB_driver.php');}//第二处 $params['dbdriver'].'_driver.php' 该文件可不调整,实际未修改该文件,为了方便调试也加了//mysql驱动对应system/database/drivers/mysql/mysql_driver.php,mysql的最后执行方法在这里,//包括数据库打开和关闭、查询等,可以该文件增加相应日志查看读写分离是否有效if(file_exists(APPPATH.'core/database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php')) {  require_once(APPPATH.'core/database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');} else {  require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');}//将当前group name赋值给param,方便判断$params['group_name'] = $active_group; /* End of file DB.php *//* Location: ./application/core/database/DB.php */            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表