+++ Introduction {{Doctrine_Db}} is a wrapper for PDO database object. Why should you consider using {{Doctrine_Db}} instead of PDO? # It provides efficient eventlistener architecture, hence its easy to add new aspects to existing methods like on-demand-caching # {{Doctrine_Db}} lazy-connects database. Creating an instance of {{Doctrine_Db}} doesn't directly connect database, hence {{Doctrine_Db}} fits perfectly for application using for example page caching. # It has many short cuts for commonly used fetching methods like {{Doctrine_Db::fetchOne()}}. # Supports PEAR-like data source names as well as PDO data source names. +++ Connecting to a database {{Doctrine_Db}} allows both PEAR-like DSN (data source name) as well as PDO like DSN as constructor parameters. Getting an instance of {{Doctrine_Db}} using PEAR-like DSN: // using PEAR like dsn for connecting pgsql database $dbh = new Doctrine_Db('pgsql://root:password@localhost/mydb'); // using PEAR like dsn for connecting mysql database $dbh = new Doctrine_Db('mysql://root:password@localhost/test'); Getting an instance of {{Doctrine_Db}} using PDO-like DSN (PDO mysql driver): $dbh = new Doctrine_Db('mysql:host=localhost;dbname=test', $user, $pass); Getting an instance of {{Doctrine_Db}} using PDO-like DSN (PDO sqlite with memory tables): $dbh = new Doctrine_Db('sqlite::memory:'); Handling connection errors: try { $dbh = new Doctrine_Db('mysql:host=localhost;dbname=test', $user, $pass); foreach ($dbh->query('SELECT * FROM foo') as $row) { print_r($row); } $dbh = null; } catch (PDOException $e) { print 'Error!: ' . $e->getMessage() . ' '; die(); } +++ Using event listeners {{Doctrine_Db}} has a pluggable event listener architecture. It provides before and after listeners for all relevant methods. Every listener method takes one parameter: a {{Doctrine_Db_Event}} object, which holds info about the occurred event. Every listener object must either implement the {{Doctrine_Db_EventListener_Interface}} or {{Doctrine_Overloadable}} interface. Using {{Doctrine_Overloadable}} interface only requires you to implement {{__call()}} which is then used for listening all the events. class OutputLogger extends Doctrine_Overloadable { public function __call($m, $a) { print $m . ' called!'; } } For convience you may want to make your listener class extend {{Doctrine_Db_EventListener}} which has empty listener methods, hence allowing you not to define all the listener methods by hand. The following listener, 'MyLogger', is used for listening only {{onPreQuery}} and {{onQuery}} methods. class MyLogger extends Doctrine_Db_EventListener { public function onPreQuery(Doctrine_Db_Event $event) { print 'database is going to be queried!'; } public function onQuery(Doctrine_Db_Event $event) { print 'executed: ' . $event->getQuery(); } } Now the next thing we need to do is bind the eventlistener objects to our database handler. // using PDO dsn for connecting sqlite memory table $dbh = Doctrine_Db::getConnection('sqlite::memory:'); class MyLogger extends Doctrine_Db_EventListener { public function onPreQuery(Doctrine_Db_Event $event) { print "database is going to be queried!"; } public function onQuery(Doctrine_Db_Event $event) { print "executed: " . $event->getQuery(); } } $dbh->setListener(new MyLogger()); $dbh->query("SELECT * FROM foo"); // prints: // database is going to be queried // executed: SELECT * FROM foo class MyLogger2 extends Doctrine_Overloadable { public function __call($m, $a) { print $m." called!"; } } $dbh->setListener(new MyLogger2()); $dbh->exec("DELETE FROM foo"); // prints: // onPreExec called! // onExec called! +++ Chaining listeners {{Doctrine_Db}} supports event listener chaining. It means multiple listeners can be attached for listening the events of a single instance of {{Doctrine_Db}}. For example you might want to add different aspects to your {{Doctrine_Db}} instance on-demand. These aspects may include caching, query profiling etc. // using PDO dsn for connecting sqlite memory table $dbh = Doctrine_Db::getConnection('sqlite::memory:'); class Counter extends Doctrine_Db_EventListener { private $queries = 0; public function onQuery(Doctrine_Db_Event $event) { $this->queries++; } public function count() { return count($this->queries); } } class OutputLogger extends Doctrine_Overloadable { public function __call($m, $a) { print $m." called!"; } } $counter = new Counter(); $dbh->addListener($counter); $dbh->addListener(new OutputLogger()); $dbh->query("SELECT * FROM foo"); // prints: // onPreQuery called! // onQuery called! print $counter->count(); // 1