Was just reviewing this post and noticed that I've referred to a project which is now dead. Here's the latest extension of the MySQLi class which I use:
PHP Code:
<?php /** * MySQLiExtended Class * * Extends mysqli class to add functionality: * 1) Support for table prefixes. * Tables can be accessed by using TABLE_{TABLE_NAME} (e.g. TABLE_CUSTOMER) * for automatic table prefixing. * 2) Error testing output * 3) Extend {@link MySQLiExtended::multi_query multi_query} function to auto-clear results * 4) Add {@link MySQLiExtended::quote_smart quote_smart} function for SQL sanitization. * * Assumes existence of global $db_configuration. * $db_configuration is created by {@link index-database.php index-database.php} * * @author Jeremy Miller <support@TeraTask.com> * @copyright 2007-2008 TeraTask Technologies, LLC */
class MySQLiExtended extends mysqli { private $table_name_prefix = ''; private $table_tokens = array(); public $error_testing = false;
/** * Get Accessor * * Currently only extended to allow ->prefix for retrieving the table prefix. * */ public function __get($variable_name) { switch ($variable_name) { case 'prefix': return $this->table_name_prefix; break; } }
/** * Set Accessor * * Currently only extended to allow setting of ->prefix. * * @throws "Database Not Indexed" if $db_configuration is empty. */ public function __set($variable_name, $variable_value) { switch ($variable_name) { case 'prefix': $this->table_name_prefix = preg_replace('/[^a-z0-9\_]/i','',$variable_value); //Now, update stored array to contain the correct token/replacement values for table names global $db_configuration; if (empty($db_configuration)) { throw new Exception('Database Not Indexed'); } else { $table_tokens = array_keys($db_configuration); arsort($table_tokens); foreach ($table_tokens as $table_name) { $token = 'TABLE_'.strtoupper(str_replace(' ', '_', $table_name)); $this->table_tokens[$token] = $this->table_name_prefix.$table_name; } } break; } }
/** * @ignore */ public function prepare($query) { //Parse TABLE_{TABLE_NAME} tokens $query = $this->table_tokens($query);
//Execute parent query function return parent::prepare($query); }
/** * @ignore */ public function query($query) { //Parse TABLE_{TABLE_NAME} tokens if ($this->error_testing) { echo 'Before Auto Change:'.$query.'<br />'."\n"; } $query = $this->table_tokens($query); if ($this->error_testing) { echo 'After Auto Change:'.$query.'<br />'."\n"; }
//Execute parent query function return parent::query($query); } /** * Extended to auto-clear result set. * * mysqli::multi_query returns all result sets by default. * This function adds the clear_result_set parameter to allow * automatic result set clearing. * * @param string $query * @param string $clear_result_set */ public function multi_query($query, $clear_result_set = false) { //Parse TABLE_{TABLE_NAME} tokens if ($this->error_testing) { echo 'Before Auto Change:'.$query.'<br />'."\n"; } $query = $this->table_tokens($query); if ($this->error_testing) { echo 'After Auto Change:'.$query.'<br />'."\n"; }
//Execute query and store results $query_results = parent::multi_query($query);
//Clear result cache -- useful for UPDATE or INSERT commands where the result set isn't needed if ($clear_result_set) { while ($this->next_result()) { $result = $this->use_result(); if ($result instanceof mysqli_result) { $result->free(); } } } return $query_results; }
/** * Database value preparation * * Prevent SQL injection by using this function CORRECTLY. * Quoting presumes the value will be inside of double quotes. * Automatically de-escapes the value on servers which automatically add * quotes for POST submissions. * * NOTE: Original source taken from the PHP site * * @param mixed $value * @param bool $add_quotes Add single quotes if not numeric. * @param bool $allow_wildcards Set false to disallow % and _ characters * @param bool $require_quotes Forces quotes even if numeric * @param bool $escape_for_db Whether to apply real_escape_string() * @return string Updated query value */ public function quote_smart($value, $add_quotes = true, $allow_wildcards = true, $require_quotes = false, $escape_for_db = true) { // Stripslashes if (get_magic_quotes_gpc()) { $value = stripslashes($value); }
if (!is_numeric($value)) { if ($escape_for_db) { $value = $this->real_escape_string($value); } if ($add_quotes) { $require_quotes = true; } } if ($require_quotes) { $value = "'" . $value . "'"; } if (!$allow_wildcards) { $value = str_replace('%','\%',$value); $value = str_replace('_','\_',$value); } return $value; } /** * Replace prepared statement ? symbols with their parameters. * * Syntax is of the form MySQLiExtended::prepared_statement_replaced($prepared_statement_sql, $replacement_1, $replacement_2, ...); * * Use for debugging prepared statements. * * @param string $prepared_statement_sql * @param string $replacement_x * @return string Update query string */ public static function prepared_statement_replaced() { $numargs = func_num_args();