PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Database connection fallback with PDO

Note: This article was originally published at Planet PHP on 4 June 2012.
Planet PHP

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: classADBAextendsAPDOA{ ApublicAfunctionA__construct($dsn,A$login,A$pass,A$backup_dsn)A{ AAAAAAAAtryA{ AAAAAAAAAAAparent::__construct($dsn,A$login,A$pass); AAAAAAAA}AcatchA(ExceptionA$e)A{ AAAAAAAAAAAAparent::__construct($backup_dsn,A$login,A$pass); AAAAAAAA} A} } ?

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: classADBAextendsAPDOA{ ApublicAfunctionA__construct($dsn,A$login,A$pass,A$backup_dsn)A{ AAAAAAAAtryA{ AAAAAAAAAAAparent::__construct($dsn,A$login,A$pass,A

Truncated by Planet PHP, read more at the original (another 1077 bytes)