//Paul Tero, 26/6/2010 //This function can select, update, insert and delete from a database. The database must be already connected to //and selected with mysql_connect and mysql_select_db. The arguments are: //$table: the database table, for selects this can include a join, and even columns FROM table //$where: the where condition, or a number to operate on a specific row, if an array then is swapped to the 3rd argument //$order: order by column for selecting data (if a string), limit (if a number), null for deleting data, data to insert/update (if an array) //$debug: output each database statement before running it, or email errors if an email address, or IP address to show debug statements, defaults to false //$idcol: the column used for the id number, defaults to "id" //$datecol: the column used for date the row was created, used to make a verification hash, defaults to "createddate" //returns: id number for single insert/update, null for deletes and multiple insert/update, an array when selecting by id, or array of arrays //Example usages: //$customer = SuperDatabase ('customers', 14); //returns the customer with the id number 14 //$customers = SuperDatabase ('customers'); //all customers in whatever their order is in the database //$customers = SuperDatabase ('name, telephone FROM customers'); //just the name and telephone //$customers = SuperDatabase ('customers', 'status=1', 'name'); //returns an array of customers with the status of 1, ordered by name //SuperDatabase ('customers', 14, null); //deletes the customer with id number 14 //SuperDatabase ('customers', array ('id'=>14, 'name'=>'Paul')); //changes name of customer 14 to Paul //SuperDatabase ('customers', '', array ('id'=>14, 'name'=>'Paul')); //same as above //SuperDatabase ('customers', 14, array ('name'=>'Paul')); //same as above //SuperDatabase ('customers', 'status=1', array ('status'=>2)); //changes all customers with status 1 to status 2 //$customerid = SuperDatabase ('customers', array ('name'=>'Paul')); //inserting a new customer function SuperDatabase ($table, $where='', $order='', $debug=false, $idcol='id', $datecol='createddate') { $error = ''; $return = ''; //store the error and what will be returned if ($debugemail = strpos ($debug, '@') ? $debug : '') $debug = false; //debug email and debug if (strpos ($debug, '.')) $debug = $_SERVER['REMOTE_ADDR'] == $debug; //only for a certain IP address //For inserts and updates, the data could be passed in as the second argument if (is_array ($where)) {$order = $where; $where = '';} //First do a couple checks for SQL injection $check = $where; if (is_string ($order)) $check .= " $order"; //check the where and order by columns if (preg_match ('/\bUNION\b|\bJOIN\b|1=1/i', $check)) return null; //attempting some SQL injection so deny them if (substr_count ($check, "'") % 2 == 1) return null; //something with an uneven number of quotes, could be SQL injection //if (preg_match ("/^[^=]*'/", $check)) return null; //a quote before a =, could be SQL injection, or could be a LIKE, so disabled this check //Form the where condition if an id number was passed in instead of a string if (preg_match ('/^\d+$/', trim ($where))) { //a number was passed in for the where condition, which can be 0 if (!is_null ($order) && !is_array ($order)) $order = 1; //limit to returning one result $where = "$idcol='" . intval ($where) . "'"; //lookup by id } //Do a delete if null was passed in for the data if (is_null ($order)) { $sql = "DELETE FROM $table WHERE $where"; if ($debug) echo "
About to delete from the table $table: $sql
"; if (!mysql_query ($sql)) $error = "Error running $sql to delete data from $table: " . mysql_error(); $return = null; //return a null } //Do an insert or update if an array was passed in else if (is_array ($order)) { $data = $order; //rename the variable so it's easier to understand $sql = "SHOW COLUMNS FROM $table"; //get the columns from the table if ($debug) echo "Getting all the columns from the table $table: $sql
";
if (!($results = mysql_query ($sql))) $error = "The table $table doesn't exist or doesn't have any columns."; //tables doesn't exist
else { //there are columns in the table
$allcols = array(); while ($row = mysql_fetch_array ($results)) $allcols[$row['Field']] = $row['Type']; //get the columns
$dataid = isset ($data[$idcol]) && intval ($data[$idcol]) > 0 ? intval ($data[$idcol]) : 0; //get the id number of the data
if ($dataid) $where = "$idcol='$dataid'"; //if the data contained an id number, then override the $where to just update this row
$changes = array(); foreach ($data as $col=>$value) { //figure out the changes which need to be made
if (preg_match ('/_removefile$/', $col)) {$col = substr ($col, 0, -11); $value = '';} //clear reference to uploaded file
if (!isset ($allcols[$col])) continue; //this column is not in this table
else if ($col == $idcol) continue; //this is the id column
else if (preg_match ('/^\S+\(/', $value)) {$changes[$col] = $value; continue;} //pass straight through as it's a function
else if ($allcols[$col] == "date") $value = date ('Y-m-d', strtotime ($value)); //it's a date
else if ($allcols[$col] == "datetime") $value = date ('Y-m-d H:i:s', strtotime ($value)); //it's a date time
if (!preg_match ("/^'|\\\\\\\\'|[^\\\\]'/", $value)) $value = stripSlashes ($value); //strip extra slashes
$value = function_exists ("mysql_real_escape_string") ? mysql_real_escape_string ($value) : addSlashes ($value); //escape
$changes[$col] = "'$value'"; //put this change into an array
} //for each change to the data
if (!$changes) $error = "There is no data to insert or update for the table $table."; //nothing to do
else { //data to insert/update
if (!$where && $datecol && isset ($allcols[$datecol])) $changes[$datecol] = 'NOW()'; //record the date the row was created
$sql = $where ? 'UPDATE' : 'INSERT INTO'; //is this an insert or an update
$sql .= " $table SET "; foreach ($changes as $col=>$value) $sql .= "$col=$value, "; //update each column
$sql = substr ($sql, 0, -2); //remove the last comma and space
if ($where) $sql .= " WHERE $where"; //add the where condition
if ($debug) echo "Insert/updating row $dataid in the table $table: $sql
";
if (!mysql_query ($sql)) $error = "Error running $sql to insert/update row $dataid in $table: " . mysql_error();
else { //no error running the statement
if (!$where) $dataid = mysql_insert_id(); //if this was an insert, then get the id number inserted
//add any uploaded file data to the incoming data too if a "filepath" is passed in with the incoming data
if ($dataid>0 && isset ($data['filepath']) && isset ($_FILES) && $_FILES) {
$path = realpath ($data['filepath']); //see if we can find the path
if (!$path) $path = realpath ($_SERVER['DOCUMENT_ROOT'] . '/' . $data['filepath']); //or if absolute
if ($path && is_dir ($path)) { //the path exists for uploading files
$path = preg_replace ('~/$~', '', $path); //take off a trailing /
foreach ($_FILES as $findex=>$fdata) { //for each of the uploaded files
if (!$fdata['tmp_name']) continue; //nothing to upload
if (!isset ($allcols[$findex])) continue; //this column is not in the table
if (preg_match ('/php|inc$/', $fdata['name'])) continue; //no PHP files allowed
$fdir = $path . '/' . $table . '-' . sprintf ("%06d", $dataid) . '-' . $findex . '/';
if ($debug) echo "
Trying to upload $findex file $fdata[name] to $fdir
";
if (!is_dir ($fdir)) mkdir ($fdir); //make the directory to store the file
if (!is_dir ($fdir)) continue; //can't make the directory for putting the file into
$fname = strtolower (preg_replace ('/[^\w\d\.]+/', '-', $fdata['name'])); //clean up name
if (function_exists ('glob')) foreach (glob ("$fdir/*") as $ffile) unlink ($ffile);
if (!$fname) continue; //no name, so don't move the file or save to the database
move_uploaded_file ($fdata['tmp_name'], $fdir . $fname); //move the uploaded file
if (!file_exists ($fdir . $fname)) continue; //file was not moved successfully into place
$fdir = substr ($fdir, strlen ($_SERVER['DOCUMENT_ROOT'])); //remove doc root before saving
$sql = "UPDATE $table SET $findex='$fdir$fname' WHERE $idcol='$dataid'";
if ($debug) echo "File saved, about to save file location to database: $sql
";
if (!mysql_query ($sql)) $error = "Error running $sql to save file location";
} //for each uploaded files
}
else $error = "Can't find the directory $data[filepath] for uploading files";
}
if ($debug) echo "Rows affected: " . mysql_affected_rows() . "
About to select: $sql
"; list($tu,$ts)=explode(' ',microtime()); $timer=(float)$tu+(float)$ts;}
if (!($results = mysql_query ($sql))) $error = "Error running $sql to select data from $table: " . mysql_error();
else { //not an error selecting data
if ($debug) {echo "Rows found: " . mysql_num_rows ($results) . ", took: "; list($tu,$ts)=explode(' ',microtime()); $timer-=((float)$tu+(float)$ts); echo round(-$timer*1000)/1000 . " seconds