Extending PEAR’s DB class

This took me quite a while to figure out, so I probably should write it down. My basic goal was to have global db error handling by overloading the query method. Because of the inheritance heirarchy in the DB classes this was tough to nail down at first. Using the DB class in it’s vanila form looks like this:

require_once('DB.php');
$db =& DB::connect("mysql://user:pass@host/dbname");
$sql = "SELECT * FROM foo";
$query = $db->query($sql);
$result = $query->fetchRow();

Which is a slightly different API than the DB class I was using at ResTek for a long time:

require_once('DB.php');
$db = new db('database');
$sql = "SELECT * FROM foo";
$query = $db->query($sql);
$result = $db->fetch_assoc($query);

It was a little annoying to rewrite code / retrain my brain for PEAR’s API, but it makes things easier.

Now when you call DB::connect, you do not get a DB object back but a DB_mysql (or whatever DB you specified). I tried making my own MY_DB class to return the right objects. Disaster. I was successful with copying and renaming the classes DB, DB_common, and DB_mysql. Now I was able to insert my own code in the DB_mysql::query method. Sweet.

I eventually trimmed it down to just extending the DB_mysql class. Here’s a sniplet that works very well for me:

class DB_MIKE_mysql extends DB_mysql {

    function &query($sql) {

        $query =& DB_mysql::query($sql);

        if ($this->isError($query)) {

            /* custom error code here */

        }

        return $query;
    }
}

$db =& DB::connect("MIKE_mysql://user:pass@host/dbname");

The DB::connect function loads a class called DB_$WHATS_IN_THE_DSN, so getting the custom class name right was the tricky part. PEAR seems to like this on php4 and php5.

Comments are closed.