A case study of _php analysis of MySQL multi-database and read-write separation by Yii

Source: Internet
Author: User
Tags php framework yii

In this paper, we analyze the method to realize MySQL multiple database and read-write separation by Yii. 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 everything that today's Web 2.0 application development needs and is one of the most powerful frameworks, and here's how to implement the MySQL multi-Library and read-write separation of Yii

Some time ago for SNS products made the architectural design, in the framework of the program has done a lot of related stress testing, the final selection of yiiframework, as for why not the company's internal PHP framework, in fact, the reason is very full, although the company's framework is "predecessors" of the hard accumulation, but not mature enough, Without the experience of a large project, it is like a young boy who is inexperienced. Yii as a well-known open source product, there must be a lot of people in the use, means that there are a number of people in the maintenance, and before that, I also used yii to develop large projects, Yii's design pattern and its easy to expand features enough to worthy the task.

SNS and the general social product is the difference is it eventually to bear the test of large concurrency and large data, architecture design to consider these issues, Web distributed, load balancing, Distributed file storage, MySQL distributed or read and write separation, NoSQL and a variety of caching, these are essential applications, This article is about MySQL library and master-slave read-write separation in Yii configuration and use.

Yii By default does not support read-write separation, we can use Yii event-driven mode to achieve MySQL read and write separation.

Yii provides a powerful Cactiverecord database operation class, by rewriting the Getdbconnection method to implement database switching, and then through event BeforeSave, BeforeDelete, Beforefind To achieve the switching of read and write server, also need two profiles dbconfig and Modelconfig respectively Configure the database master server and model corresponding to the database name, with code
dbconfig.php files are as follows:

Copy Code code 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 is as follows:
Copy Code code as follows:
<?php
Return Array (
Key is the database name, value is model
' Passport ' => array (' User ', ' Post '),
' Microblog ' => array (' ... '),
);
?>

Activerecord.php is as follows:
Copy Code code as follows:
/**
* Based on the encapsulation of Cactiverecord class, realize the separation of multi-Library and master-slave reading
* All model must inherit some classes.
*
*/
Class ActiveRecord extends Cactiverecord
{
Model configuration
Public $modelConfig = ';
Database configuration
Public $dbConfig = ';
Define a multiple 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 for 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 ()
{
Returns directly if the specified database object exists
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.));
}
/**
* 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 the database name
*/
Private Function Getdbname () {
if ($this->dbname)
return $this->dbname;
$modelName = Get_class ($this->model ());
$this->modelconfig = $this->getconfig (' modelconfig ');
Get the database name of 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);
According to the type of the corresponding configuration (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];
}
To add a 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 Primary database before saving data
*/
protected function BeforeSave () {
Parent::beforesave ();
$this->changeconn (' write ');
return true;
}
/**
* Select 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 object
*/
Public Function Dbwrite () {
return $this->changeconn (' write ');
}
/**
* Get Slave Library objects
*/
Public Function DBRead () {
return $this->changeconn (' read ');
}
}

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

I hope this article will help you with the PHP program design based on the 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.