Now that we have one master connection and four slaves setup we can
override the Doctrine_Record and Doctrine_Query classes to add our
logic for switching between the connections for read and write
functionality. All writes will go to the master connection and all reads
will be randomly distributed across the available slaves.

Lets start by adding our logic to Doctrine_Query by extending it with
our own MyQuery class and switching the connection in the preQuery()
hook.

classMyQueryextendsDoctrine_Query{// Since php doesn't support late static binding in 5.2// we need to override this method to instantiate a new MyQuery// instead of Doctrine_Querypublicstaticfunctioncreate($conn=null){returnnewMyQuery($conn);}publicfunctionpreQuery(){// If this is a select query then set connection to one of the slavesif($this->getType()==Doctrine_Query::SELECT){$this->_conn=Doctrine_Manager::getInstance()->getConnection('slave_'.rand(1,4));// All other queries are writes so they need to go to the master}else{$this->_conn=Doctrine_Manager::getInstance()->getConnection('master');}}}

Now we have queries taken care of, but what about when saving records?
We can force the connection for writes to the master by overriding
:php:class:Doctrine_Record and using it as the base for all of our models.

abstractclassMyRecordextendsDoctrine\_Record{publicfunctionsave(Doctrine_Connection$conn=null){// If specific connection is not provided then lets force the connection// to be the masterif($conn===null){$conn=Doctrine_Manager::getInstance()->getConnection('master');}parent::save($conn);}}

All done! Now reads will be distributed to the slaves and writes are
given to the master connection. Below are some examples of what happens
now when querying and saving records.

First we need to setup a model to test with.

classUserextendsMyRecord{publicfunctionsetTableDefinition(){$this->setTableName('user');$this->hasColumn('username','string',255,array('type'=>'string','length'=>'255'));$this->hasColumn('password','string',255,array('type'=>'string','length'=>'255'));}}// The save() method will happen on the master connection because it is a write$user=newUser();$user->username='jwage';$user->password='changeme';$user->save();// This query goes to one of the slaves because it is a read$q=newMyQuery();$q->from('User u');$users=$q->execute();print_r($users->toArray(true));// This query goes to the master connection because it is a write $q =newMyQuery();$q->delete('User')->from('User u')->execute();