CodeIgniter 3.0支持數據庫讀寫分離方式

網上有部分方法,支持讀寫分離,但過於複製,並且有的只支持2.0版本的,如今改善一個,支持3.0版本的讀寫分離php

本次修改的環境是:mysql

  • CodeIgniter 3.0.3nginx

  • MySQL 5.5+sql

  • PHP 5.5.9數據庫

  • nginx 1.1.8app

步驟一:修改application/config/database.php

數據庫讀、寫鏈接參數的配置。ui

$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
);

步驟2、修改 system/core/Controller.php 加入下列代碼

public $db_write = null;

步驟3、修改system/database/DB.php

找到 this

$DB->initialize();

在上面加入spa

//支持 讀寫分離
    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;
    }

步驟4、修改 system/database/DB_driver.php

添加對SQL的數據庫鏈接選擇路由功能。debug

添加實例變量

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 完美的解決了 讀寫分離的操做

本文參考了部分網上的資源

相關文章
相關標籤/搜索