getMessage()]
* @param int $error_code [OPTIONAL] The error number [$exception->getCode()]
*/
protected static function ErrorEvent($error, $error_code = 0) {
// Send this error to the PHP error log
if (empty($error_code)) {
error_log($error, 0);
} else {
error_log(self::PDO_DB . ' error ' . $error_code . ': ' . $error, 0);
}
}
/**
* Connects to a MySQL PDO database.
*
* NOTE: I chose to pass back an error on this routine because a database
* connection error is serious and the author might want to send out email
* or other communications to alert them. If the connection is successful,
* then FALSE is returned (as in there was not an error to report).
*
* @param string $username Database user name
* @param string $password Database password
* @param string $database Database or schema name
* @param string $hostname [OPTIONAL] Host name of the server
* @param boolean $silent_errors [OPTIONAL] Show no errors on queries
* @return boolean/string The error if there was one otherwise FALSE
*/
public static function Connect($username, $password, $database,
$hostname = 'localhost', $silent_errors = false) {
try {
// Connect to the MySQL database
$GLOBALS[self::PDO_DB] = new PDO('mysql:' .
'host=' . $hostname . ';' .
'dbname=' . $database,
$username, $password);
// If we are connected...
if ($GLOBALS[self::PDO_DB]) {
// The default error mode for PDO is PDO::ERRMODE_SILENT.
// With this setting left unchanged, you'll need to manually
// fetch errors, after performing a query
if (!$silent_errors) {
$GLOBALS[self::PDO_DB]->setAttribute(
PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// Connection was successful
$error = false;
} else {
// Connection was not successful
$error = true;
}
// If there was an error...
} catch (PDOException $e) {
// Get the error
$error = 'Database Connection Error (' . __METHOD__ . '): ' .
$e->getMessage();
// Send the error to the error event handler
self::ErrorEvent($error, $e->getCode());
}
// Return the results
return $error;
}
/**
* Executes a SQL statement using PDO
*
* @param string $sql SQL
* @param array $placeholders [OPTIONAL] Associative array placeholders for binding to SQL
* array("name' => 'Cathy', 'city' => 'Cardiff')
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @return boolean (Last INSERT ID if INSERT or) TRUE if success otherwise FALSE
*/
public static function Execute($sql, $placeholders = false, $debug = false) {
// Set the variable initial values
$query = false;
$count = false;
$id = false;
$time = false;
// Is there already a transaction pending? No nested transactions in MySQL!
$existing_transaction = $GLOBALS[self::PDO_DB]->inTransaction();
// Is this a SQL INSERT statement? Check the first word...
$insert = (strtoupper(strtok(trim($sql), ' '))) === 'INSERT';
// Set a flag
$return = false;
try {
// Begin a transaction
if (!$existing_transaction) {
$GLOBALS[self::PDO_DB]->beginTransaction();
}
// Create the query object
$query = $GLOBALS[self::PDO_DB]->prepare($sql);
// If there are values in the passed in array
if (!empty($placeholders) &&
is_array($placeholders) &&
count($placeholders) > 0) {
// Loop through the placeholders and values
foreach ($placeholders as $field => $value) {
// Determine the datatype
if (is_int($value)) {
$datatype = PDO::PARAM_INT;
} elseif (is_bool($value)) {
$datatype = PDO::PARAM_BOOL;
} elseif (is_null($value)) {
$datatype = PDO::PARAM_NULL;
} elseif ($value instanceof DateTime) {
$value = $value->format('Y-m-d H:i:s');
$placeholders[$field] = $value;
$datatype = PDO::PARAM_STR;
} else {
$datatype = PDO::PARAM_STR;
}
// Bind the placeholder and value to the query
$query->bindValue($field, $value, $datatype);
}
}
// Start a timer
$time_start = microtime(true);
// Execute the query
$query->execute();
// Find out how long the query took
$time_end = microtime(true);
$time = $time_end - $time_start;
// If this was an INSERT...
if ($insert) {
// Get the last inserted ID (has to be done before the commit)
$id = $GLOBALS[self::PDO_DB]->lastInsertId();
}
// Debug only
if ($debug) {
// Rollback the transaction
if (!$existing_transaction) {
$GLOBALS[self::PDO_DB]->rollback();
}
// Output debug information
self::DumpDebug(__FUNCTION__,
$sql, $placeholders, $query, false, $time, $count, $id);
// Exit
die();
}
// Commit the transaction
if (!$existing_transaction) {
$GLOBALS[self::PDO_DB]->commit();
}
// If this was an INSERT...
if ($insert) {
// Hand back the last inserted ID
$return = $id;
} else {
// Query was successful
$return = true;
}
} catch (PDOException $e) { // If there was an error...
// Get the error
$error = 'Database Error (' . __METHOD__ . '): '
. $e->getMessage() . ' ' . $sql;
// Send the error to the error event handler
self::ErrorEvent($error, $e->getCode());
// If we are in debug mode...
if ($debug) {
// Output debug information
self::DumpDebug(__FUNCTION__,
$sql, $placeholders, $query, false, $time, $count, $id, $error);
}
// Rollback the transaction
if (!$existing_transaction) {
$GLOBALS[self::PDO_DB]->rollback();
}
} catch (Exception $e) { // If there was an error...
// Get the error
$error = 'General Error (' . __METHOD__ . '): ' . $e->getMessage();
// Send the error to the error event handler
self::ErrorEvent($error, $e->getCode());
// If we are in debug mode...
if ($debug) {
// Output debug information
self::DumpDebug(__FUNCTION__,
$sql, $placeholders, $query, false, $time, $count, $id, $error);
}
// Rollback the transaction
if (!$existing_transaction) {
$GLOBALS[self::PDO_DB]->rollback();
}
}
// Clean up
unset($query);
// If this was a successful INSERT with an ID...
if ($return && $id) {
// Return the ID instead
$return = $id;
}
// Return [the ID or] true if success and false if failure
return $return;
}
/**
* Executes a SQL query using PDO and returns records
*
* @param string $sql SQL
* @param array $placeholders [OPTIONAL] Associative array placeholders for binding to SQL
* array('name' => 'Cathy', 'city' => 'Cardiff')
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @param integer $fetch_parameters [OPTIONAL] PDO fetch style record options
* @return array Array with values if success otherwise FALSE
*/
public static function Query($sql, $placeholders = false,
$debug = false, $fetch_parameters = PDO::FETCH_ASSOC) {
// Set the variable initial values
$query = false;
$return = false;
$time = false;
try {
// Create the query object
$query = $GLOBALS[self::PDO_DB]->prepare($sql);
// If there are values in the passed in array
if (!empty($placeholders) &&
is_array($placeholders) &&
count($placeholders) > 0) {
// Loop through the placeholders and values
foreach ($placeholders as $field => $value) {
// Determine the datatype
if (is_int($value)) {
$datatype = PDO::PARAM_INT;
} elseif (is_bool($value)) {
$datatype = PDO::PARAM_BOOL;
} elseif (is_null($value)) {
$datatype = PDO::PARAM_NULL;
} elseif ($value instanceof DateTime) {
$value = $value->format('Y-m-d H:i:s');
$placeholders[$field] = $value;
$datatype = PDO::PARAM_STR;
} else {
$datatype = PDO::PARAM_STR;
}
// Bind the placeholder and value to the query
$query->bindValue($field, $value, $datatype);
}
}
// Start a timer
$time_start = microtime(true);
// Execute the query
$query->execute();
// Find out how long the query took
$time_end = microtime(true);
$time = $time_end - $time_start;
// Query was successful
$return = $query->fetchAll($fetch_parameters);
// Debug only
if ($debug) {
// Output debug information
self::DumpDebug(__FUNCTION__,
$sql, $placeholders, $query, $return, $time, count($return));
}
} catch (PDOException $e) { // If there was an error...
// Get the error
$error = 'Database Error (' . __METHOD__ . '): '
. $e->getMessage() . ' ' . $sql;
// Send the error to the error event handler
self::ErrorEvent($error, $e->getCode());
// If we are in debug mode...
if ($debug) {
// Output debug information
self::DumpDebug(__FUNCTION__, $sql, $placeholders, $query,
$return, $time, false, false, $error);
}
// die($e->getMessage());
$return = false;
} catch (Exception $e) { // If there was an error...
// Get the error
$error = 'General Error (' . __METHOD__ . '): ' . $e->getMessage();
// Send the error to the error event handler
self::ErrorEvent($error, $e->getCode());
// If we are in debug mode...
if ($debug) {
// Output debug information
self::DumpDebug(__FUNCTION__, $sql, $placeholders, $query,
$return, $time, false, false, $error);
}
// die($e->getMessage());
$return = false;
}
// Clean up
unset($query);
// Return results if success and false if failure
return $return;
}
/**
* Executes a SQL query using PDO and returns one row
*
* @param string $sql SQL
* @param array $placeholders [OPTIONAL] Associative array placeholders for binding to SQL
* array('name' => 'Cathy', 'city' => 'Cardiff')
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @param integer $fetch_parameters [OPTIONAL] PDO fetch style record options
* @return array Array with values if success otherwise FALSE
*/
public static function QueryRow($sql, $placeholders = false,
$debug = false, $fetch_parameters = PDO::FETCH_ASSOC) {
// It's better on resources to add LIMIT 1 to the end of your SQL
// statement if there are multiple rows that will be returned
$results = self::Query($sql, $placeholders, $debug, $fetch_parameters);
// If one or more records were returned
if (is_array($results) && count($results) > 0) {
// Return the first element of the array which is the first row
return $results[key($results)];
} else {
// No records were returned
return false;
}
}
/**
* Executes a SQL query using PDO and returns a single value only
*
* @param string $sql SQL
* @param array $placeholders Associative array placeholders for binding to SQL
* array('name' => 'Cathy', 'city' => 'Cardiff')
* @param booplean $debug If set to true, will output results and query info
* @return unknown A returned value from the database if success otherwise FALSE
*/
public static function QueryValue($sql, $placeholders = false, $debug = false) {
// It's better on resources to add LIMIT 1 to the end of your SQL
// if there are multiple rows that will be returned
$results = self::QueryRow($sql, $placeholders, $debug, PDO::FETCH_NUM);
// If a record was returned
if (is_array($results)) {
// Return the first element of the array which is the first row
return $results[0];
} else {
// No records were returned
return false;
}
}
/**
* Selects records from a table using PDO
*
* @param string $table Table name
* @param array $values [OPTIONAL] Array or string containing the field names
* array('name', 'city') or 'name, city'
* @param array/string [OPTIONAL] $where Array containing the fields and values or a string
* $where = array();
* $where['id >'] = 1234;
* $where[] = 'first_name IS NOT NULL';
* $where['some_value <>'] = 'text';
* @param array/string [OPTIONAL] $order Array or string containing field order
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @param integer $fetch_parameters [OPTIONAL] PDO fetch style record options
* @return array Array with values if success otherwise FALSE
*/
public static function Select($table, $values = '*', $where = false,
$order = false, $debug = false, $fetch_parameters = PDO::FETCH_ASSOC) {
// If the values are in an array
if (is_array($values)) {
// Join the fields
$sql = 'SELECT ' . implode(', ', $values);
} else { // It's a string
// Create the SELECT
$sql = 'SELECT ' . trim($values);
}
// Create the SQL WHERE clause
$where_array = self::WhereClause($where);
$sql .= ' FROM ' . trim($table) . $where_array['sql'];
// If the order values are in an array
if (is_array($order)) {
// Join the fields
$sql .= ' ORDER BY ' . implode(', ', $order);
} elseif ($order) { // It's a string
// Specify the order
$sql .= ' ORDER BY ' . trim($order);
}
// Execute the query and return the results
return self::Query($sql, $where_array['placeholders'],
$debug, $fetch_parameters);
}
/**
* Selects a single record from a table using PDO
*
* @param string $table Table name
* @param array $values [OPTIONAL] Array or string containing the field names
* array('name', 'city') or 'name, city'
* @param array/string [OPTIONAL] $where Array containing the fields and values or a string
* $where = array();
* $where['id >'] = 1234;
* $where[] = 'first_name IS NOT NULL';
* $where['some_value <>'] = 'text';
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @param integer $fetch_parameters [OPTIONAL] PDO fetch style record options
* @return array Array with values if success otherwise FALSE
*/
public static function SelectRow($table, $values = '*', $where = false,
$debug = false, $fetch_parameters = PDO::FETCH_ASSOC) {
// If the values are in an array
if (is_array($values)) {
// Join the fields
$sql = 'SELECT ' . implode(', ', $values);
} else { // It's a string
// Create the SELECT
$sql = 'SELECT ' . trim($values);
}
// Create the SQL WHERE clause
$where_array = self::WhereClause($where);
$sql .= ' FROM ' . trim($table) . $where_array['sql'];
// Make sure only one row is returned
$sql .= ' LIMIT 1';
// Execute the query and return the results
return self::QueryRow($sql, $where_array['placeholders'],
$debug, $fetch_parameters);
}
/**
* Selects a single record from a table using PDO
*
* @param string $table Table name
* @param string $field The name of the field to return
* @param array/string [OPTIONAL] $where Array containing the fields and values or a string
* $where = array();
* $where['id >'] = 1234;
* $where[] = 'first_name IS NOT NULL';
* $where['some_value <>'] = 'text';
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @param integer $fetch_parameters [OPTIONAL] PDO fetch style record options
* @return array Array with values if success otherwise FALSE
*/
public static function SelectValue($table, $field, $where = false, $debug = false) {
// Return the row
$results = self::SelectRow($table, $field, $where, $debug, PDO::FETCH_NUM);
// If a record was returned
if (is_array($results)) {
// Return the first element of the array which is the first row
return $results[0];
} else {
// No records were returned
return false;
}
}
/**
* Inserts a new record into a table using PDO
*
* @param string $table Table name
* @param array $values Associative array containing the fields and values
* array('name' => 'Cathy', 'city' => 'Cardiff')
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @return boolean Returns the last inserted ID or TRUE otherwise FALSE
*/
public static function Insert($table, $values, $debug = false) {
// Create the SQL statement with PDO placeholders created with regex
$sql = 'INSERT INTO ' . trim($table) . ' ('
. implode(', ', array_keys($values)) . ') VALUES ('
. implode(', ', preg_replace('/^([A-Za-z0-9_-]+)$/', ':${1}', array_keys($values)))
. ')';
// Execute the query
return self::Execute($sql, $values, $debug);
}
/**
* Updates an existing record into a table using PDO
*
* @param string $table Table name
* @param array $values Associative array containing the fields and values
* array('name' => 'Cathy', 'city' => 'Cardiff')
* @param array/string $where [OPTIONAL] Array containing the fields and values or a string
* $where = array();
* $where['id >'] = 1234;
* $where[] = 'first_name IS NOT NULL';
* $where['some_value <>'] = 'text';
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @return boolean TRUE if success otherwise FALSE
*/
public static function Update($table, $values, $where = false, $debug = false) {
// Create the initial SQL
$sql = 'UPDATE ' . trim($table) . ' SET ';
// Create SQL SET values
$output = array();
foreach ($values as $key => $value) {
$output[] = $key . ' = :' . $key;
}
// Concatenate the array values
$sql .= implode(', ', $output);
// Create the SQL WHERE clause
$where_array = self::WhereClause($where);
$sql .= $where_array['sql'];
// Execute the query
return self::Execute($sql,
array_merge($values, $where_array['placeholders']), $debug);
}
/**
* Deletes a record from a table using PDO
*
* @param string $table Table name
* @param array/string $where [OPTIONAL] Array containing the fields and values or a string
* $where = array();
* $where['id >'] = 1234;
* $where[] = 'first_name IS NOT NULL';
* $where['some_value <>'] = 'text';
* @param booplean $debug [OPTIONAL] If set to true, will output results and query info
* @return boolean TRUE if success otherwise FALSE
*/
public static function Delete($table, $where = false, $debug = false) {
// Create the SQL
$sql = 'DELETE FROM ' . trim($table);
// Create the SQL WHERE clause
$where_array = self::WhereClause($where);
$sql .= $where_array['sql'];
// Execute the query
return self::Execute($sql, $where_array['placeholders'], $debug);
}
/**
* Begin transaction processing
*
*/
public static function TransactionBegin() {
try {
// Begin transaction processing
$success = $GLOBALS[self::PDO_DB]->beginTransaction();
} catch (PDOException $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('Database Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
} catch (Exception $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('General Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
}
return $success;
}
/**
* Commit and end transaction processing
*
*/
public static function TransactionCommit() {
try {
// Commit and end transaction processing
$success = $GLOBALS[self::PDO_DB]->commit();
} catch (PDOException $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('Database Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
} catch (Exception $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('General Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
}
return $success;
}
/**
* Roll back transaction processing
*
*/
public static function TransactionRollback() {
try {
// Roll back transaction processing
$success = $GLOBALS[self::PDO_DB]->rollback();
} catch (PDOException $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('Database Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
} catch (Exception $e) { // If there was an error...
// Return false to show there was an error
$success = false;
// Send the error to the error event handler
self::ErrorEvent('General Error (' . __METHOD__ . '): ' .
$e->getMessage(), $e->getCode());
}
return $success;
}
/**
* Converts a Query() or Select() array of records into a simple array
* using only one column or an associative array using another column as a key
*
* @param array $array The array returned from a PDO query using fetchAll
* @param string $value_field The name of the field that holds the value
* @param string $key_field [OPTIONAL] The name of the field that holds the key
* making the return value an associative array
* @return array Returns an array with only the specified data
*/
public static function ConvertQueryToSimpleArray($array, $value_field, $key_field = false) {
// Create an empty array
$return = array();
// Loop through the query results
foreach ($array as $element) {
// If we have a key
if ($key_field) {
// Add this key
$return[$element[$key_field]] = $element[$value_field];
} else { // No key field
// Append to the array
$return[] = $element[$value_field];
}
}
// Return the new array
return $return;
}
/**
* This function returns a SQL query as an HTML table
*
* @param string $sql SQL
* @param array $placeholders [OPTIONAL] Associative array placeholders for binding to SQL
* array("name' => 'Cathy', 'city' => 'Cardiff')
* @param boolean $showCount (Optional) TRUE if you want to show the row count,
* FALSE if you do not want to show the count
* @param string $styleTable (Optional) Style information for the table
* @param string $styleHeader (Optional) Style information for the header row
* @param string $styleData (Optional) Style information for the cells
* @return string HTML containing a table with all records listed
*/
public static function GetHTML($sql, $placeholders = false, $showCount = true,
$styleTable = null, $styleHeader = null, $styleData = null) {
// Set default style information
if ($styleTable === null) {
$tb = "border-collapse:collapse;empty-cells:show";
} else {
$tb = $styleTable;
}
if ($styleHeader === null) {
$th = "border-width:1px;border-style:solid;background-color:navy;color:white";
} else {
$th = $styleHeader;
}
if ($styleData === null) {
$td = "border-width:1px;border-style:solid";
} else {
$td = $styleData;
}
// Get the records
$records = DB::Query($sql, $placeholders);
// If there was no error...
if (is_array($records)) {
// If records were returned...
if (count($records) > 0) {
// Begin the table
$html = "";
if ($showCount) $html = "Total Count: " . count($records) . "
\n";
$html .= "
| " . htmlspecialchars($value) . " | \n"; } $html .= "\t
| " . htmlspecialchars($value) . " | \n"; } $html .= "\t
";
print_r($error);
}
// If the number of seconds is specified...
if ($time !== false) {
// Show how long it took
print "\n--DEBUG " . $source . " TIMER FROM " . self::PDO_DB . "--\n\n";
echo number_format($time, 6) . ' ms';
}
// Output the SQL
print "\n--DEBUG " . $source . " SQL FROM " . self::PDO_DB . "--\n";
print_r($sql);
// If there were placeholders passed in...
if ($placeholders) {
// Show the placeholders
print "\n--DEBUG " . $source . " PARAMS FROM " . self::PDO_DB . "--\n";
print_r($placeholders);
}
// If a query object exists...
if ($query) {
// Show the query dump
print "\n--DEBUG " . $source . " DUMP FROM " . self::PDO_DB . "--\n";
print_r($query->debugDumpParams());
}
// If records were returned...
if ($count !== false) {
// Show the count
print "\n--DEBUG " . $source . " ROW COUNT FROM " . self::PDO_DB . "--\n";
print_r($count);
}
// If this was an INSERT with an ID...
if ($id) {
// Show the last inserted ID
print "\n--DEBUG LAST INSERTED ID FROM " . self::PDO_DB . "--\n";
print_r($id);
}
// If records were returned...
if ($records) {
// Show the rows returned
print "\n--DEBUG " . $source . " RETURNED RESULTS FROM " . self::PDO_DB . "--\n";
print_r($records);
}
// End the debug output
print "\n--DEBUG " . $source . " END FROM " . self::PDO_DB . "--\n