This is my first PHP5 class, and isn't completed. I wanted to try updating a PHP4 class, and also practice writing standard, commented code. I have a framework I developed in PHP4 that uses ? as placeholders in queries, then protects against SQL injection. PDO obviously does this for me, but I wanted to avoid having to bind params/values so I could keep the same format. Basically like this:

$dbh = Compass_DB::getInstance();
$stmt = $dbh->query('SELECT id, name FROM test WHERE id = ? ORDER BY name DESC', $id);

while($row = $stmt->fetch())
{
	print $row->name . '<br />';
}

// Another Example
$stmt = $dbh->query('SELECT id, name FROM test WHERE Check-In BETWEEN ? AND ?',
	$date1,
	$date2
);

Allowing for as many values to be binded automatically (if any at all). Another element of this class is it allows you to set a default fetch mode (I personally like fetching objects), and the class will maintain that unless otherwise specified when calling $stmt->fetch()

I'd love to hear any critiques (even the smallest of suggestions). The focus is on a lightweight and fast wrapper for MySQL and PgSQL.

<?php

/**
 * This is a lightweight wrapper around the PDO extension that 
 * makes the extension easier to work with. Implements the 
 * Singleton design pattern.
 *
 */

class Compass_DB extends PDO
{
	/**
	 * Singleton Instance
	 *
	 * @var boolean
	 */
	private static $_instance = false;

/**
 * Fetch Mode for all queries
 *
 * @var mixed
 */
public $fetch_mode = PDO::FETCH_OBJ;

/**
 * Holds the total number of queries executed.
 *
 * @var int
 */
public static $count = 0;

/**
 * Establishes a PDO connection based on the driver.
 * Currently accepts Pdo_Mysql and Pdo_Pgsql as values.
 *
 * @param object $conf The desired database driver, database name, and login credentials.
 * @return void
 */	
public function __construct($conf)
{
	$driver = str_ireplace('Pdo_', '', $conf->driver);
	$driver = strtolower($driver);

	parent::__construct($driver.':host='.$conf->host.';dbname='.$conf->database, $conf->username, $conf->password);
	$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Compass_DB_Statement', array($this)));
}

/**
 * Grabs Singleton instance of object. If it doesn't exist, attempts to create it.
 *
 * @return object
 */
public static function getInstance()
{
	if(!self::$_instance)
	{
		$conf = Compass_Config::getInstance()->fetchBySection('Database');

		self::$_instance = new Compass_DB($conf);
	}

	return self::$_instance;
}

public function exec()
{
	$vals = func_get_args();
	$stmt = call_user_func_array(array($this, 'query'), $vals);

	return $stmt->rowCount();
}

public function query()
{
	$vals = func_get_args();
	++$this->count;

	if(count($vals) == 1)
	{
		return parent::query($vals[0]);
	}

	$stmt = parent::prepare(array_shift($vals));

	foreach($vals as $k => $v)
	{
		$stmt->bindValue($k+1, $v);
	}

	$stmt->execute();
	return $stmt;
}

/**
 * Dynamically builds an SQL Update statement and executes.
 *
 * @param string $table The table to be updated
 * @param array $vals The array of values where the array keys hold the field names
 * @param array|string $condition String or array for SQL WHERE clause
 * @return int $count Number of rows affected
 */
public function update($table, $vals, $condition)
{

}

public function insert($table, $vals = array())
{

}

public function dbPairs()
{
	$vals = func_get_args();
	$stmt = call_user_func_array(array($this, 'query'), $vals);
	$retval = array();

	while($row = $stmt->fetch(PDO::FETCH_NUM))
	{
		$retval[$row[0]] = $row[1];
	}

	return $retval;
}
}

/**
 * This is a lightweight wrapper around the PDOStatement class that 
 * currently deals with setting the appropriate fetch mode based on
 * what is set in the Compass_DB class.
 *
 */

class Compass_DB_Statement extends PDOStatement
{
	/**

 * Holds PDO object.
 *
 * @val object
 */
private $_dbh = null;

protected function __construct($dbh)
{
	$this->_dbh = $dbh;
}

public function fetch($mode = '')
{
	$mode = empty($mode) ? $this->_dbh->fetch_mode : $mode;
	return parent::fetch($mode);
}

public function fetchAll($mode = '')
{
	$mode = empty($mode) ? $this->_dbh->fetch_mode : $mode;
	return parent::fetchAll($mode);
}
}

?>
    Write a Reply...