My stab at it. Tried to keep it as simple as possible, while still maintaining some real-world conveniences.
Handles unicode and uses loose comparison for readability. Be nice ;-)
<?php
header('Content-type: text/html; charset=utf-8');
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
// display_errors can be changed to 0 in production mode to
// suppress PHP's error messages
/*
Can be used for testing
$_POST['id'] = 1;
$_POST['name'] = 'Markus';
*/
$config = array(
'host' => '127.0.0.1',
'user' => 'my_user',
'pass' => 'my_pass',
'db' => 'my_database'
);
# Connect and disable mysql error output
$connection = @mysql_connect($config['host'],
$config['user'], $config['pass']);
if (!$connection) {
trigger_error('Unable to connect to database: '
. mysql_error(), E_USER_ERROR);
}
if (!mysql_select_db($config['db'])) {
trigger_error('Unable to select db: ' . mysql_error(),
E_USER_ERROR);
}
if (!mysql_set_charset('utf8')) {
trigger_error('Unable to set charset for db connection: '
. mysql_error(), E_USER_ERROR);
}
$result = mysql_query(
'UPDATE tablename SET name = "'
. mysql_real_escape_string($_POST['name'])
. '" WHERE id = "'
. mysql_real_escape_string($_POST['id']) . '"'
);
if ($result) {
echo htmlentities($_POST['name'], ENT_COMPAT, 'utf-8')
. ' updated.';
} else {
trigger_error('Unable to update db: '
. mysql_error(), E_USER_ERROR);
}
I decided to jump the gun and just put something up. It's something to start with. Throws an exception on error.
function executeQuery($query, $args) {
$cleaned = array_map('mysql_real_escape_string', $args);
if($result = mysql_query(vsprintf($query, $cleaned))) {
return $result;
} else {
throw new Exception('MySQL Query Error: ' . mysql_error());
}
}
function updateTablenameName($id, $name) {
$query = "UPDATE tablename SET name = '%s' WHERE id = %d";
return executeQuery($query, array($name, $id));
}
try {
updateTablenameName($_POST['id'], $_POST['name']);
} catch(Exception $e) {
echo $e->getMessage();
exit();
}
/**
* Rule #0: never trust users input!
*/
//sanitize integer value
$id = intval($_GET['id']);
//sanitize string value;
$name = mysql_real_escape_string($_POST['name']);
//1. using `dbname`. is better than using mysql_select_db()
//2. names of tables and columns should be quoted by "`" symbol
//3. each variable should be sanitized (even in LIMIT clause)
$q = mysql_query("UPDATE `dbname`.`tablename` SET `name`='".$name."' WHERE `id`='".$id."' LIMIT 0,1 ");
if ($q===false)
{
trigger_error('Error in query: '.mysql_error(), E_USER_WARNING);
}
else
{
//be careful! $name contains user's data, remember Rule #0
//always use htmlspecialchars() to sanitize user's data in output
print htmlspecialchars($name).' updated';
}
########################################################################
//Example, how easily is to use set_error_handler() and trigger_error()
//to control error reporting in production and dev-code
//Do NOT use error_reporting(0) or error_reporting(~E_ALL) - each error
//should be fixed, not muted
function err_handler($errno, $errstr, $errfile, $errline)
{
$hanle_errors_print = E_ALL & ~E_NOTICE;
//if we want to print this type of errors (other types we can just write in log-file)
if ($errno & $hanle_errors_print)
{
//$errstr can contain user's data, so... Rule #0
print PHP_EOL.'Error ['.$errno.'] in file '.$errfile.' in line '.$errline
.': '.htmlspecialchars($errstr).PHP_EOL;
}
//here you can write error into log-file
}
set_error_handler('err_handler', E_ALL & ~E_NOTICE & E_USER_NOTICE & ~E_STRICT & ~E_DEPRECATED);
And some explanation of comments:
//1. using `dbname`. is better than using mysql_select_db()
With using mysql_select_db you can create errors, and it will be not so easy to find and fix them.
For example, in some script you will set db1 as database, but in some function you need to set db2 as database.
After calling this function, database will be switched, and all following queries in script will be broken or will broke some data in wrong database (if names of tables and columns will coincide).
//2. names of tables and columns should be quoted by "`" symbol
Some names of columns can be also SQL-keywords, and using "`" symbol will help with that.
Also, all string-values, inserted to query, should be quoted by ' symbol.
//always use htmlspecialchars() to sanitize user's data in output
It will help you to prevent XSS-attacks.
<?
mysql_connect();
mysql_select_db("new");
$table = "test";
if($_SERVER['REQUEST_METHOD']=='POST') {
$name = mysql_real_escape_string($_POST['name']);
if ($id = intval($_POST['id'])) {
$query="UPDATE $table SET name='$name' WHERE id=$id";
} else {
$query="INSERT INTO $table SET name='$name'";
}
mysql_query($query) or trigger_error(mysql_error()." in ".$query);
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
exit;
}
if (!isset($_GET['id'])) {
$LIST=array();
$query="SELECT * FROM $table";
$res=mysql_query($query);
while($row=mysql_fetch_assoc($res)) $LIST[]=$row;
include 'list.php';
} else {
if ($id=intval($_GET['id'])) {
$query="SELECT * FROM $table WHERE id=$id";
$res=mysql_query($query);
$row=mysql_fetch_assoc($res);
foreach ($row as $k => $v) $row[$k]=htmlspecialchars($v);
} else {
$row['name']='';
$row['id']=0;
}
include 'form.php';
}
?>
form.php
<? include 'tpl_top.php' ?>
<form method="POST">
<input type="text" name="name" value="<?=$row['name']?>"><br>
<input type="hidden" name="id" value="<?=$row['id']?>">
<input type="submit"><br>
<a href="?">Return to the list</a>
</form>
<? include 'tpl_bottom.php' ?>
list.php
<? include 'tpl_top.php' ?>
<a href="?id=0">Add item</a>
<? foreach ($LIST as $row): ?>
<li><a href="?id=<?=$row['id']?>"><?=$row['name']?></a>
<? endforeach ?>
<? include 'tpl_bottom.php' ?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With