网上有部分方法,支持读写分离,但过于复制,而且有的只支持2.0版本的,现在改善一个,支持3.0版本的读写分离
本次修改的环境是:
-
CodeIgniter 3.0.3
-
MySQL 5.5+
-
PHP 5.5.9
-
nginx 1.1.8
步骤一:修改application/config/database.php
数据库读、写连接参数的配置。
$active_group = 'default';$query_builder = TRUE;$db['default'] = array( 'dsn' => '', 'hostname' => '127.0.0.1', 'username' => 'root', 'password' => '', 'database' => 'xxx', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => 1, 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, //failover 配置备用节点 'failover' => array( /* 设置多个备用数据库主机 * array( 'hostname' => 'localhost1', 'username' => '', 'password' => '', 'database' => '', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => TRUE, 'db_debug' => TRUE, 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE ), array( 'hostname' => 'localhost2', 'username' => '', 'password' => '', 'database' => '', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => TRUE, 'db_debug' => TRUE, 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE )*/ ), 'save_queries' => TRUE);//开启 $db['write'] 支持读写分离$db['write'] = array( 'dsn' => '', 'hostname' => '127.0.0.1', 'username' => 'root', 'password' => '', 'database' => 'xxx', 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => 1, 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, //failover 配置备用节点 'failover' => array(), 'save_queries' => TRUE);
步骤二、修改 system/core/Controller.php 加入下列代码
public $db_write = null;
步骤三、修改system/database/DB.php
找到
$DB->initialize();
在上面加入
//支持 读写分离 if (!empty($db['write'])){ $CI =& get_instance(); $CI->db_write = new $driver($db['write']); $DB->is_single_instance = false; $CI->db_write->is_single_instance = false; $CI->db_write->initialize(); }else{ $DB->is_single_instance = true; }
步骤四、修改 system/database/DB_driver.php
添加对SQL的数据库连接选择路由功能。
添加实例变量
public $is_single_instance = false;
并替换下面的方法
public function simple_query($sql) { if ( ! $this->conn_id) { $this->initialize(); } if($this->is_single_instance){ //不读写分离 return $this->_execute($sql); }else{ //读写分离 if(preg_match("/^\s*select/",strtolower($sql))) { return $this->_execute($sql); } else { $CI =& get_instance(); //默认选择主库!这点很重要,如果有未知功能也可以保证数据完整 $rrr = $CI->db_write->_execute($sql); return $rrr; } } }
第五骤:如果是使用默认的 mysqli连接,请注释掉 system/database/drivers/mysqli/mysqli_driver.php 的下面方法
public function insert_id(){ return $this->conn_id->insert_id; }
并在 system/database/DB_driver.php 里面新增下方法
/** * Insert ID * * @return int */ public function insert_id() { //return $this->conn_id->insert_id; if($this->is_single_instance){ return $this->conn_id->insert_id; }else{ //读写分离 $CI =& get_instance(); return $CI->db_write->conn_id->insert_id; } }
第六步:修改 system/database/DB_driver.php 里面的 close方法
/** * Close DB Connection * * @return void */ public function close() { if($this->is_single_instance){ if ($this->conn_id) { $this->_close(); $this->conn_id = FALSE; } }else{ //读写分离 $CI =& get_instance(); $CI->db_write->conn_id = FALSE; $this->conn_id = FALSE; } }
至此,CodeIgniter 3.0 完美的解决了 读写分离的操作
本文参考了部分网上的资源