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);
}
}
?>