CodeIgniter read-Write separation implementation Method _php example

Source: Internet
Author: User
Tags php file php programming codeigniter

This paper illustrates the method of CodeIgniter read-write separation. Share to everyone for your reference, specific as follows:

The current server only do master and slave, not configured read-write separation, read-write separation function only to the program to achieve, here mainly talk about CodeIgniter how to achieve read and write separation, and need to meet the following two points:

1, read-write separation should be transparent to development.

There are programs on the Web through manual load multiple db to achieve read and write separation, such separation with the business is too tight, increased the difficulty of development is not conducive to maintenance, we have to do is the default read the library, write the main library, read and write separation of transparent to the developer

2, simple configuration.

Retain the existing configuration, by adding an array to configure read-write separation, does not affect the original use.

Ideas

1, to achieve the separation of read and write is the simplest way of thinking is in the final execution of the query based on the query to determine whether to insert the main library or read from the library, so you need to find the function.

2, should only connect once the database, the next operation of the link should be reusable. That is, all the read operations are available after a heavy library is connected, and the main library is the same. So we can put the link in the CI Super object.

3, the master-slave judgment is based on the final execution of the SQL statement to judge, so the database configuration of the automatic link autoinit parameter is not set to True, if the default connection and do not need to operate the library to waste resources.

4, the model can use $THIS->DB to directly manipulate the query, no need for other adjustments.

5, do not directly modify the system under the file

Enable read-Write separation

The DB class of CI is fixed to read files under System, and we can do so by appropriate rewriting. The first is loader.php, in which the database method is used to load the object, fixed reference system/database/db.php file, we judge whether there is a custom db.php file, existence is introduced.

Rewrite 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/*

Then we create the database/db.php under Application/core, which has only one DB method for reading the configuration file and initializing the work. There are also two places to rewrite:

overrides db.php

//db_driver.php is the parent class for all drives, the method of the final execution of the query in the file//first modified to determine whether the custom db_driver.php exists, and exists to introduce 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 '); //Second $params [' Dbdriver ']. ' _driver.php ' This file does not adjust, actually did not modify the file, in order to facilitate debugging also add a//mysql driver corresponding System/database/drivers/mysql/mysql_ Driver.php,mysql Final execution method here,//including database open and close, query, etc., you can increase the corresponding log to see whether read-write separation is valid 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 ');
 
///Assign the current group name to Param for easy judgment $params [' group_name '] = $active _group; /* End of File db.php/* Location:./application/core/database/db.php/* 

The entire db.php adjustment is also basically the introduction of the file, the introduction of group name is to facilitate the subsequent judgment, not introduced can be configured through the host, database name. If you want to force off Autoint, you can delete the following paragraph in db.php:

if ($DB->autoinit = = TRUE)
{
  $DB->initialize ();
}

The next step is the core of the place. Read and write separation based on query statement.
The Simple_query method in db_driver.php can be understood as the last method of executing the SQL statement, where we can make a judgment of the database link.

Rewrite db_driver.php

Adds an attribute that represents the current group Var $active _group;
Add properties, using the Force Main library var $db _force_master;
This method is to execute the query must pass through, we can judge by the type here to use which link. The function simple_query ($sql) {//load_db_proxy_setting method is written here in the helper, or it can be written directly in the class, and in the helper you need to load the helper in automatic loading/ The purpose of this method is to determine which link to use based on the current link group name and SQL read-write type, and whether to enforce use of the main library.
  Use the main library OR the library? A single point of failure can be considered in the load balancing of the primary repository.
  That is, a usable array of configurations is returned based on 3 parameters. $proxy _setting = load_db_proxy_setting ($this->group_name, $this->is_write_type ($sql), $this->db_force_
  Master);
    if (Is_array ($proxy _setting) &&! empty ($proxy _setting)) {$proxy _setting_key = key ($proxy _setting);
    $this->group_name = $proxy _setting_key; Reassign the current configuration to the properties of the class, and if the database.php is configured with a DSN string, you will need to handle a foreach in Load_db_proxy_setting ($proxy _setting[$proxy _setting_
    Key] as $key => $val) {$this-> $key = $val;
    }//define link ID is conn_ prefix $proxy _conn_id = ' conn_ '. $proxy _setting_key;
    $CI = & Get_instance (); Assign to CI super objects or read directly from CI Super objects if (isset ($CI-> $proxy _conn_id) && is_resource ($CI-> $proxy_conn_id) {$this->conn_id = $CI-> $proxy _conn_id;
      else {$this->conn_id = false;
      $this->initialize ();
    $CI-> $proxy _conn_id = $this->conn_id;
  //force only once valid, the next query is invalid, prevent the main library $this->reset_force_master ();
  } if (! $this->conn_id) {$this->initialize ();
return $this->_execute ($sql); In some cases, the main library is enforced, and the public Function Force_master () {$this->db_force_master = TRUE.} Public Function Reset_forc E_master () {$this->db_force_master = FALSE;}/* End of File db_driver.php/* Location:./application/core/databa

 se/db_driver.php *

Read-write separation here is basically achieved, but do things to the end, linked database objects need to shut down, you can do in the public controller after the completion of the connection.

The Close method is also available in db_driver.php, and can you consider whether you can turn it off in this method? This is not considered to be a good one.

Close database Links

 class My_controller extends Ci_controller {public Function __construct () {par
    Ent::__construct ();
    $this->load->service (' Common/helper_service ', NULL, ' helper '); The following paragraph closes the database objects and database links in the CI Super object, and the Register_shutdown_function (function () {foreach (get_object_) is closed in the object codeigniter.php of DB.  VARs ($this) as $key => $val) {if (substr ($key, 0, 3) = = ' Db_ ' && is_object ($this->{$key}) &&
        Method_exists ($this->{$key}, ' close ') {$this->{$key}->close (); } if (substr ($key, 0, 5) = = ' Conn_ ' && is_resource ($this->{$key})) {$this->db->_close ($
          Val);
        unset ($this->{$key});
  }
      }
    }); }/* End of File my_controller.php/* Location:./application/core/my_controller.php/* 

The use of the model, in order to make each model can use $THIS->DB, and not many times to connect the database, this is also put the link in the CI Super object. Here, even if you do not read and write separation can be so handled, you can easily connect multiple db, the specific model to use other libraries only need to be in the constructor to pass the group name.

Model Adjustment

Public function __construct ($group _name = ')
{
  parent::__construct ();
  $this->initdb ($group _name);
Private Function Initdb ($group _name = ')
{
  $db _conn_name = $this->getdbname ($group _name);
  $CI = & Get_instance ();
  if (Isset ($CI->{$db _conn_name}) && Is_object ($CI->{$db _conn_name})) {
    $this->db = $CI->{$db _conn_name};
  } else {
    $CI->{$db _conn_name} = $this->db = $this->load->database ($group _name, TRUE);
  }
Private Function Getdbname ($group _name = ')
{
  if ($group _name = = ') {
    $db _conn_name = ' db ';
  } else {
    $db _conn_name = ' db_ '. $group _name;
  }
  return $db _conn_name;
}
/* End of File my_model.php
////* Location:./application/core/my_model.php/*

The last way to configure the database is simply to configure an array on the original basis. Whether to use a double master or a master more from the view of the configuration here. First of all think directly in the original configuration plus key to deal with, but the relationship between the main and from the load_db_proxy_setting is not so clear, here the definition of the way to determine the implementation of the way.

database.php Configuration

$_master_slave_relation = Array (
  ' default_master ' => array (' default_slave1 ', ' default_slave2 ', ' default_ Slave3 '),
);
/* End of File database.php
////* Location:./application/config/database.php/*

The beginning of the database link is not placed in the CI Super object, found that the load multiple models each time the link opened, so after the completion of read and write separation must be tested, you can open and close the database link to see whether the expected execution (method corresponding to Application/core/ Db_connect and _close in database/drivers/mysql/mysql_driver.php). The most important two points of the entire tuning process are the Simple_query method and the closing of the database link in the constructor. The adjustment in the model is to more convenient link multiple libraries, not realize read and write separation is also so adjusted, the commonly used method is independent of a file, My_model to inherit.

The implementation of MySQL read and write separation of the middleware is very much, in the absence of these can be controlled by the program to achieve the separation of read and write. Of course, this is just a read-write separation, you can force the main library. If you want a better way to distribute, think about how the load_db_proxy_setting is distributed.

More interested readers of the CodeIgniter framework can view the site's topics: The CodeIgniter Introductory Course and the CI (CodeIgniter) framework Advanced Tutorial.

I hope this article will help you with your PHP programming based on the CodeIgniter framework.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.