Simple PHP PDO Wrapper Class

For the last few years I’ve been using PHP Data Objects [PDO] in all of my projects, mainly for the use of parameterized queries to avoid SQL injection. Now with PHP pushing to remove the old mysql_* functions and get the community into PDO or mySQLi I’ve found myself sharing this code more and more often. So I’m finally posting it up here so I don’t have to keep copy/pasting this after editing out all the stuff that’s specific to me.

As a bonus, this also implements the Singleton design pattern, so you can use a static Mysql_DB::getInstance() function anywhere in you code to grab the instance of the database with very little hassle.

<?php
Class Mysql_DB {

private static $instance;
private $dbh;

private function __construct() {}

public static function getInstance() {
	if( !self::$instance ) {
		self::$instance = new Mysql_DB();
	}
	return self::$instance;
}

public function initDB($conn_info) {
	if( ! $this->checkArray($conn_info, 4, 5) ) {
		Throw new Exception("Incorrect number of arguments for MySQL connection.");
	} else if( ! (isset($conn_info['hostname']) && isset($conn_info['dbname']) && isset($conn_info['username']) && isset($conn_info['password'])) ) {
		Throw new Exception("MySQL connection info does not contain all necessary parts.");
	}

	$uri = sprintf("mysql:host=%s;dbname=%s", $conn_info['hostname'], $conn_info['dbname']);
	$this->dbh = new PDO($uri, $conn_info['username'], $conn_info['password']);
}

public function doQuery($query, $params=NULL) {
	$this->requireInit();
	$dbh = $this->dbh;
	if(!$query) {
		return NULL;
	} else {
		$sth = $dbh->prepare($query);
		if($sth->execute($params)) {
			return $sth->fetchAll(PDO::FETCH_ASSOC);
		} else {
			$err_arr = $sth->errorInfo();
			$err_msg = sprintf("SQLSTATE ERR: %s<br />\nmySQL ERR: %s<br />\nMessage: %s<br />\n", $err_arr[0], $err_arr[1], $err_arr[2]);
			Throw new Exception($err_msg);
		}
	}
}

private function checkArray($arr, $min_ele, $max_ele, $allow_empty=FALSE) {
	$cnt = count($arr);
	if( ($cnt < $min_ele) || ($cnt > $max_ele) ) { return false; }
	else if( !$allow_empty ) {
		foreach( $arr as $element ) {
			if( empty($element) ) { return false; }
		}
	}
	return true;
}

private function requireInit() {
	if( !isset($this->dbh) ) {
		throw Exception('Database connection has not been initialized.');
	}
}

} //-- End of model class

So to use it you’ll have something like:

<?php
require('class.Mysql_DB.php');

$database_credentials = array(
        'hostname'      => 'mysql.yourdomain.com',
        'dbname'        => 'your_db',
        'username'      => 'user',
        'password'      => 'pass'
);

$dbh = Mysql_DB::getInstance();
$dbh->initDB($database_credentials);

$query = "SELECT * FROM user WHERE username LIKE ? AND email LIKE ?";
$query_args = array('Sammitch', 'someone@somewhere.com');

$rs = $dbh->doQuery($query, $query_args);

Enjoy!