Created
August 14, 2014 19:49
-
-
Save gabrysiak/cd114aa51d20d44ce520 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Tom Gabrysiak | |
* @version 1.2 | |
* PDO Wrapper Class | |
* | |
* Example Usage: | |
* | |
* CONNECT: | |
* $db = new DB("mysql:host=localhost;dbname=db", "dbuser", "dbpass"); | |
* | |
* | |
* ERROR HANDLING | |
* $db->setErrorCallbackFunction("myErrorHandler"); | |
* | |
* | |
* SELECT: | |
* var_dump($db->select('tablename', 'gender = "male"')); | |
* | |
* | |
* PREPARED SELECT: | |
* $search = "J"; | |
* $bind = array( | |
* ":search" => "%$search" | |
* ); | |
* $results = $db->select("mytable", "FName LIKE :search", $bind); | |
* | |
* | |
* DELETE: | |
* $db->delete("mytable", "Age < 30"); | |
* | |
* | |
* PREPARED DELETE: | |
* $lname = "Doe"; | |
* $bind = array( | |
* ":lname" => $lname | |
* ) | |
* $db->delete("mytable", "LName = :lname", $bind); | |
* | |
* | |
* INSERT: | |
* $insert = array( | |
* "FName" => "John", | |
* "LName" => "Doe", | |
* "Age" => 26, | |
* "Gender" => "male" | |
* ); | |
* $db->insert("mytable", $insert); | |
* | |
* | |
* UPDATE: | |
* $update = array( | |
* "FName" => "Jane", | |
* "Gender" => "female" | |
* ); | |
* $db->update("mytable", $update, "FName = 'John'"); | |
* | |
* | |
* PREPARED UPDATE: | |
* $update = array( | |
* "Age" => 24 | |
* ); | |
* $fname = "Jane"; | |
* $lname = "Doe"; | |
* $bind = array( | |
* ":fname" => $fname, | |
* ":lname" => $lname | |
* ); | |
* $db->update("mytable", $update, "FName = :fname AND LName = :lname", $bind); | |
* | |
* | |
* RAW SQL QUERY: | |
* $sql = <<<STR | |
* CREATE TABLE mytable ( | |
* ID int(11) NOT NULL AUTO_INCREMENT, | |
* FName varchar(50) NOT NULL, | |
* LName varchar(50) NOT NULL, | |
* Age int(11) NOT NULL, | |
* Gender enum('male','female') NOT NULL, | |
* PRIMARY KEY (ID) | |
* ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; | |
* STR; | |
* $db->run($sql); | |
*/ | |
class DB extends PDO { | |
/** | |
* Error messages generated | |
* @var mixed | |
*/ | |
private $error; | |
/** | |
* The query string | |
* @var mixed | |
*/ | |
private $sql; | |
/** | |
* Optional prepared bind paramater array | |
* @var array | |
*/ | |
private $bind; | |
/** | |
* Error callback to display the message defaults to "print_r" if non specified | |
* @var mixed | |
*/ | |
private $errorCallbackFunction; | |
/** | |
* Format type of the error message defaults to "html" if non specified | |
* @var mixed | |
*/ | |
private $errorMsgFormat; | |
/** | |
* Instantiate class | |
* @param string $dsn | |
* @param string $user | |
* @param string $passwd | |
*/ | |
public function __construct($dsn, $user="", $passwd="") { | |
$options = array( | |
PDO::ATTR_PERSISTENT => true, | |
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION | |
); | |
try { | |
parent::__construct($dsn, $user, $passwd, $options); | |
} catch (PDOException $e) { | |
$this->error = $e->getMessage(); | |
} | |
} | |
/** | |
* Format bind parameter array | |
* @param mixed $bind | |
* @return array | |
*/ | |
private function cleanup($bind) { | |
if(!is_array($bind)) { | |
if(!empty($bind)) | |
$bind = array($bind); | |
else | |
$bind = array(); | |
} | |
return $bind; | |
} | |
/** | |
* Called when error thown and returns properly formatted error message | |
* using errorCallbackFunction if it has been set other wise use defaults | |
* @return mixed | |
*/ | |
private function debug() { | |
if(!empty($this->errorCallbackFunction)) { | |
$error = array("Error" => $this->error); | |
if(!empty($this->sql)) | |
$error["SQL Statement"] = $this->sql; | |
if(!empty($this->bind)) | |
$error["Bind Parameters"] = trim(print_r($this->bind, true)); | |
$backtrace = debug_backtrace(); | |
if(!empty($backtrace)) { | |
foreach($backtrace as $info) { | |
if($info["file"] != __FILE__) | |
$error["Backtrace"] = $info["file"] . " at line " . $info["line"]; | |
} | |
} | |
$msg = ""; | |
if($this->errorMsgFormat == "html") { | |
if(!empty($error["Bind Parameters"])) | |
$error["Bind Parameters"] = "<pre>" . $error["Bind Parameters"] . "</pre>"; | |
$css = trim(file_get_contents(dirname(__FILE__) . "/error.css")); | |
$msg .= '<style type="text/css">' . "\n" . $css . "\n</style>"; | |
$msg .= "\n" . '<div class="db-error">' . "\n\t<h3>SQL Error</h3>"; | |
foreach($error as $key => $val) | |
$msg .= "\n\t<label>" . $key . ":</label>" . $val; | |
$msg .= "\n\t</div>\n</div>"; | |
} | |
elseif($this->errorMsgFormat == "text") { | |
$msg .= "SQL Error\n" . str_repeat("-", 50); | |
foreach($error as $key => $val) | |
$msg .= "\n\n$key:\n$val"; | |
} | |
$func = $this->errorCallbackFunction; | |
$func($msg); | |
} | |
} | |
/** | |
* Create database delete query | |
* @param string $table | |
* @param string $where | |
* @param string $bind | |
* @return object | |
*/ | |
public function delete($table, $where, $bind="") { | |
$sql = "DELETE FROM " . $table . " WHERE " . $where . ";"; | |
$this->run($sql, $bind); | |
} | |
/** | |
* Get database metadata | |
* @param string $table | |
* @param string $info | |
* @return array | |
*/ | |
private function filter($table, $info) { | |
$driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); | |
if($driver == 'sqlite') { | |
$sql = "PRAGMA table_info('" . $table . "');"; | |
$key = "name"; | |
} | |
elseif($driver == 'mysql') { | |
$sql = "DESCRIBE " . $table . ";"; | |
$key = "Field"; | |
} | |
else { | |
$sql = "SELECT column_name FROM information_schema.columns WHERE table_name = '" . $table . "';"; | |
$key = "column_name"; | |
} | |
if(false !== ($list = $this->run($sql))) { | |
$fields = array(); | |
foreach($list as $record) | |
$fields[] = $record[$key]; | |
return array_values(array_intersect($fields, array_keys($info))); | |
} | |
return array(); | |
} | |
/** | |
* Create a database insert query clean it up and execute | |
* @param string $table | |
* @param array $info | |
* @return object | |
*/ | |
public function insert($table, $info) { | |
$fields = $this->filter($table, $info); | |
$sql = "INSERT INTO " . $table . " (" . implode($fields, ", ") . ") VALUES (:" . implode($fields, ", :") . ");"; | |
$bind = array(); | |
foreach($fields as $field) | |
$bind[":$field"] = $info[$field]; | |
return $this->run($sql, $bind); | |
} | |
/** | |
* Create a database select query clean it up and execute | |
* @param string $table | |
* @param string $where | |
* @param string $bind | |
* @param string $fields | |
* @return object | |
*/ | |
public function select($table, $where="", $bind="", $fields="*") { | |
$sql = "SELECT " . $fields . " FROM " . $table; | |
if(!empty($where)) | |
$sql .= " WHERE " . $where; | |
$sql .= ";"; | |
return $this->run($sql, $bind); | |
} | |
/** | |
* Create database update query clean it up and execute | |
* @param string $table | |
* @param array $info | |
* @param string $where | |
* @param string $bind | |
* @return object | |
*/ | |
public function update($table, $info, $where, $bind="") { | |
$fields = $this->filter($table, $info); | |
$fieldSize = sizeof($fields); | |
$sql = "UPDATE " . $table . " SET "; | |
for($f = 0; $f < $fieldSize; ++$f) { | |
if($f > 0) | |
$sql .= ", "; | |
$sql .= $fields[$f] . " = :update_" . $fields[$f]; | |
} | |
$sql .= " WHERE " . $where . ";"; | |
$bind = $this->cleanup($bind); | |
foreach($fields as $field) | |
$bind[":update_$field"] = $info[$field]; | |
return $this->run($sql, $bind); | |
} | |
/** | |
* Execute query using PDO | |
* @param string $sql | |
* @param string $bind | |
* @return object | |
*/ | |
public function run($sql, $bind="") { | |
$this->sql = trim($sql); | |
$this->bind = $this->cleanup($bind); | |
$this->error = ""; | |
try { | |
$pdostmt = $this->prepare($this->sql); | |
if($pdostmt->execute($this->bind) !== false) { | |
if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql)) | |
return $pdostmt->fetchAll(PDO::FETCH_ASSOC); | |
elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) | |
return $pdostmt->rowCount(); | |
} | |
} catch (PDOException $e) { | |
$this->error = $e->getMessage(); | |
$this->debug(); | |
return false; | |
} | |
} | |
/** | |
* Set the type of errorCallbackFunction to use | |
* @param string $errorCallbackFunction | |
* @param string $errorMsgFormat | |
*/ | |
public function setErrorCallbackFunction($errorCallbackFunction, $errorMsgFormat="html") { | |
//Variable functions for won't work with language constructs such as echo and print, so these are replaced with print_r. | |
if(in_array(strtolower($errorCallbackFunction), array("echo", "print"))) | |
$errorCallbackFunction = "print_r"; | |
if(function_exists($errorCallbackFunction)) { | |
$this->errorCallbackFunction = $errorCallbackFunction; | |
if(!in_array(strtolower($errorMsgFormat), array("html", "text"))) | |
$errorMsgFormat = "html"; | |
$this->errorMsgFormat = $errorMsgFormat; | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment