Yii implements MySQL multi-database and read-write separation instance Analysis _php instance

Source: Internet
Author: User
In this paper, the method of implementing the MySQL multi-database and read-write separation is analyzed. Share to everyone for your reference. The specific analysis is as follows:

The YII framework is a high-performance PHP framework for developing large Web applications based on components. Yii provides almost all of the functions and the most powerful framework needed for Web 2.0 application development today, and we will introduce the methods of Yii implementing MySQL multi-Library and read-write separation.

A period of time for the SNS products to do the architecture design, in the program framework to do a lot of relevant pressure test, the final selection of yiiframework, as for why did not choose the company's internal PHP framework, in fact, the rationale is very full, although the company's framework is "predecessors" of the hard accumulation, but after all, not mature enough, Without the experience of large-scale projects, like a inexperienced young boy. Yii as a well-known open source products, there must be a lot of people in use, meaning that there are a number of people in the maintenance, and before that, I also used yii to develop a large project, Yii design mode and its easy to expand features enough to worthy the task.

SNS and the general social product is different is that it ultimately to withstand large concurrency and large data volume test, architecture design should consider these issues, Web distribution, load balancing, Distributed file storage, MySQL distributed or read-write separation, NoSQL and various caches, these are essential applications, This article is about MySQL sub-Library and master-slave read-write separation in Yii configuration and use.

Yii does not support read/write separation by default, we can use the event-driven mode of Yii to realize the read and write separation of MySQL.

Yii provides a powerful Cactiverecord database operation class, by overriding the Getdbconnection method to implement a database switchover, and then through the event BeforeSave, BeforeDelete, Beforefind To implement a read-write server switchover, you also need two configuration files Dbconfig and Modelconfig respectively configure the database name of the master server and model, with the code
The dbconfig.php file is as follows:
Copy CodeThe code is as follows: <?php
Return Array (
' Passport ' = = Array (
' Write ' = = Array (
' Class ' = ' cdbconnection ',
' connectionString ' = ' mysql:host=10.1.39.2;dbname=db1′,
' Emulateprepare ' = true,
' Enableparamlogging ' = true,
' Enableprofiling ' = true,
' Username ' = ' root ',
' Password ' = ',
' CharSet ' = ' utf8′,
' Schemacachingduration ' =>3600,
),
' Read ' = Array (
Array
' Class ' = ' cdbconnection ',
' connectionString ' = ' mysql:host=10.1.39.3;dbname=db1,
' Emulateprepare ' = true,
' Enableparamlogging ' = true,
' Enableprofiling ' = true,
' Username ' = ' root ',
' Password ' = ',
' CharSet ' = ' utf8′,
' Schemacachingduration ' =>3600,
),
Array
' Class ' = ' cdbconnection ',
' connectionString ' = ' mysql:host=10.1.39.4;dbname=db3′,
' Emulateprepare ' = true,
' Enableparamlogging ' = true,
' Enableprofiling ' = true,
' Username ' = ' root ',
' Password ' = ',
' CharSet ' = ' utf8′,
' Schemacachingduration ' =>3600,
),
),
),
);
modelconfig.php as follows:
Copy CodeThe code is as follows: <?php
Return Array (
Key is the database name, value is model
' Passport ' = = Array (' User ', ' Post '),
' Microblog ' = = Array (' ... '),
);
?>
activerecord.php as follows:
Copy CodeThe code is as follows:/**
* Cactiverecord Class-based package for multi-Library and master-slave read/write separation
* All model must inherit some classes.
*
*/
Class ActiveRecord extends Cactiverecord
{
Model configuration
Public $modelConfig = ';
Database configuration
Public $dbConfig = ';
Define a multi-database collection
Static $dataBase = Array ();
Current database name
Public $dbName = ';
Define library type (read or write)
Public $dbType = ' read '; ' Read ' or ' write '
/**
* Added a dbname parameter on the original basis
* @param the application scenario of string $scenario model
* @param string $dbname database name
*/
Public function __construct ($scenario = ' Insert ', $dbname = ')
{
if (!empty ($dbname))
$this->dbname = $dbname;
Parent::__construct ($scenario);
}
/**
* Overriding the Getdbconnection method of the parent class
* Multi-Library and master-slave are here to switch
*/
Public Function getdbconnection ()
{
If the specified database object exists, it is returned directly
if (self:: $dataBase [$this->dbname]!==null)
Return self:: $dataBase [$this->dbname];
if ($this->dbname = = ' db ') {
Self:: $dataBase [$this->dbname] = Yii::app ()->getdb ();
}else{
$this->changeconn ($this->dbtype);
}
if (self:: $dataBase [$this->dbname] instanceof cdbconnection) {
Self:: $dataBase [$this->dbname]->setactive (TRUE);
Return self:: $dataBase [$this->dbname];
} else
throw new CDBException (Yii::t (' Yii ', ' Model requires a ' DB ' cdbconnection application component. '));
}
/**
* Get configuration file
* @param unknown_type $type
* @param unknown_type $key
*/
Private Function GetConfig ($type = "Modelconfig", $key = ") {
$config = Yii::app ()->params[$type];
if ($key)
$config = $config [$key];
return $config;
}
/**
* Get database name
*/
Private Function Getdbname () {
if ($this->dbname)
return $this->dbname;
$modelName = Get_class ($this->model ());
$this->modelconfig = $this->getconfig (' modelconfig ');
Gets the database name of the model
if ($this->modelconfig) foreach ($this->modelconfig as $key + = $val) {
if (In_array ($modelName, $val)) {
$dbName = $key;
Break
}
}
return $dbName;
}
/**
* Switch Database connection
* @param unknown_type $dbtype
*/
protected function changeconn ($dbtype = ' read ') {
if ($this->dbtype = = $dbtype && self:: $dataBase [$this->dbname]!== null)
Return self:: $dataBase [$this->dbname];
$this->dbname = $this->getdbname ();
if (Yii::app ()->getcomponent ($this->dbname. ' _ '. $dbtype)!== null) {
Self:: $dataBase [$this->dbname] = Yii::app ()->getcomponent ($this->dbname. ' _ '. $dbtype);
Return self:: $dataBase [$this->dbname];
}
$this->dbconfig = $this->getconfig (' Dbconfig ', $this->dbname);
Configuration corresponding to the data type (from the library is a random value)
if ($dbtype = = ' Write ') {
$config = $this->dbconfig[$dbtype];
}else{
$slavekey = Array_rand ($this->dbconfig[$dbtype]);
$config = $this->dbconfig[$dbtype] [$slavekey];
}
Add database configuration to Component
if ($dbComponent = Yii::createcomponent ($config)) {
Yii::app ()->setcomponent ($this->dbname. ' _ '. $dbtype, $dbComponent);
Self:: $dataBase [$this->dbname] = Yii::app ()->getcomponent ($this->dbname. ' _ '. $dbtype);
$this->dbtype = $dbtype;
Return self:: $dataBase [$this->dbname];
} else
throw new CDBException (Yii::t (' Yii ', ' Model requires a ' changeconn ' cdbconnection application component. '));
}
/**
* Select the primary database before saving the data
*/
protected function BeforeSave () {
Parent::beforesave ();
$this->changeconn (' write ');
return true;
}
/**
* Select the primary database before deleting data
*/
protected function BeforeDelete () {
Parent::beforedelete ();
$this->changeconn (' write ');
return true;
}
/**
* Read data selection from database
*/
protected function Beforefind () {
Parent::beforefind ();
$this->changeconn (' read ');
return true;
}
/**
* Get Master Library objects
*/
Public Function Dbwrite () {
return $this->changeconn (' write ');
}
/**
* Get Slave Library objects
*/
Public Function DBRead () {
return $this->changeconn (' read ');
}
}

This is the class I have written, placed in the Components folder, and then all the model inherits the ActiveRecord class can realize the multi-Library and master-slave read and write separation, as to how to support the native SQL also use read and write separation, this class has been implemented.

It is hoped that this article is helpful to the PHP program design based on YII framework.

  • Related Article

    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.