For our database connections we PDO at work and we've extended the class with PHP to offer some other convenience functionality and wrappers. One of the things I wanted to do recently is allow the constructor of the PDO class to fail-over to our backup database connection pool in the event the primary was not available. The idea was to do something along the lines of:
PHP:
<?php
class DB extends PDO {
public function __construct($dsn, $login, $pass, $backup_dsn) {
try {
parent::__construct($dsn, $login, $pass);
} catch (Exception $e) {
parent::__construct($backup_dsn, $login, $pass);
}
}
}
?>
Essentially the code would call the PDO's own constructor, if it would fail, an exception would be raised, which would then be caught by the exception handler that will attempt to connect to the backup database connection pool. Unfortunately this simple solution does not work, the reason being, is that when PDO's constructor fails to connect, it destroys the object. Which means any attempts to use or access the object fail, even $this is equal to NULL, effectively making the 2nd construct call pointless.
While this behaviour makes sense on most cases, in some cases such as a fallback scenario illustrated above this is an undesired behaviour. To address this limitation I've written a small patch (http://ilia.ws/patch/pdo.txt) which introduces a PDO:: ATTR_KEEP_CLASS_CONN_FAILURE configuration option that can be passed to PDO's constructor, telling it to keep the object alive after a failed attempt to connect to the database, allowing re-connection to be attempted. With this patch in place, the above code can be implemented as per example below.
PHP:
<?php
class DB extends PDO {
public function __construct($dsn, $login, $pass, $backup_dsn) {
try {
parent::__construct($dsn, $login, $pass, array(PDO:: ATTR_KEEP_CLASS_CONN_FAILURE => 1));
} catch (Exception $e) {
parent::__construct($backup_dsn, $login, $pass);
}
}
}
?>