问题描述
|
我知道如何更新数据库中的行,我知道如何将数据从一页转移到另一页,但是我不知道这是更新多个不同行的数据库的好方法,只要变量不是不空。
我正在处理的是一个用户页面,该页面具有用于更改真实姓名,用户名,密码和类似名称的设置,但是我不知道如何在更改后立即进行更新。例如,如果我将\“ Username \”留空,然后按\“ Change Settings \”,则它将清空用户名行。如何使其忽略空变量?
解决方法
您很可能希望使用准备好的语句来完成此任务。既可以使代码更漂亮,更健壮,又可以避免SQL注入(替代)。
现在,由于您要根据某些条件更新不同的列,因此您可以选择几种继续操作的方法。
一种是使用多个更新语句(每个要更新的列一个)并将它们捆绑在事务中。将语句绑定在事务内将确保原子性,并且还将帮助减轻使用多个SQL语句代替一个语句(除非您有许多并发用户,否则这不太可能影响性能)的影响。
它可能看起来像这样(使用mysqli API):
$mysqli = @new mysqli(\"dbhost\", \"dbuser\", \"dbpassword\", \"dbname\");
$mysqli->autocommit(FALSE);
if ($userName) {
$stmt = $mysqli->prepare(\"UPDATE TABLE users WHERE uid=? SET username=?\");
$stmt->bind_param(\"i\", $uid);
$stmt->bind_param(\"s\", $userName);
$stmt->execute();
}
if ($password) {
$stmt = $mysqli->prepare(\"UPDATE TABLE users WHERE uid=? SET password=?\");
$stmt->bind_param(\"i\", $password);
$stmt->execute();
}
if ($firstName) {
$stmt = $mysqli->prepare(\"UPDATE TABLE users WHERE uid=? SET firstname=?\");
$stmt->bind_param(\"i\", $firstName);
$stmt->execute();
}
if ($lastName) {
$stmt = $mysqli->prepare(\"UPDATE TABLE users WHERE uid=? SET lastname=?\");
$stmt->bind_param(\"i\", $lastName);
$stmt->execute();
}
$mysqli->commit();
$mysqli->close();
为简洁起见,我省略了错误处理;您需要检查连接失败以及准备语句以及执行语句时遇到的问题。如果在第一行ѭ1之后出现任何故障,则需要致电$mysqli->rollback()
以确保未进行任何更改。
还建议您重构代码,这样它就不会重复太多了,也许是这样的:
function updateColumn($mysqli,$query,$uid,$value) {
if ($value) {
$stmt = $mysqli->prepare($query);
$stmt->bind_param(\"i\", $uid);
$stmt->bind_param(\"s\", $value);
$stmt->execute();
}
}
$mysqli = @new mysqli(\"dbhost\", \"dbname\");
$mysqli->autocommit(FALSE);
updateColumn($mysqli,\"UPDATE TABLE users WHERE uid=? SET username=?\",$userName);
updateColumn($mysqli,\"UPDATE TABLE users WHERE uid=? SET password=?\",$password);
updateColumn($mysqli,\"UPDATE TABLE users WHERE uid=? SET firstname=?\",$firstName);
updateColumn($mysqli,\"UPDATE TABLE users WHERE uid=? SET lastname=?\",$lastName);
$mysqli->commit();
$mysqli->close();
您可以进一步执行一些步骤并生成查询,这很安全,因为您不必依赖/使用用户输入来生成查询。虽然这样会很快变得毛茸茸。
其他方式将是这里已经提到的方式,或者将查询的动态生成与准备好的语句结合起来。您可能还想尝试使用PDO API进行相同的操作。
从长远来看,最好的方法可能是使用第三方ORM框架(有关建议,请参阅此相关问题)。
,为什么不使用存储在数据库中的当前值填充表单的字段?
例如。
<input type=\"text\" name=\"name\" value=\"<?php echo $(value currently in db);?>\" />
因此,即使他们没有改变,您仍然会拥有旧的价值。
,您可以这样做:
$values = array();
foreach($user_data as $key => $value)
if (isset($value) && trim($value) != \'\')
$values[] = $key.\' = \"\'.mysql_real_escape_string($value).\'\"\';
$sql = \'UPDATE users SET \'.implode(\',\',$values).\' WHERE id = \'.$id;
mysql_query($sql);
?>
,尽管您需要防止sql注入,但是这样的事情可能(未测试)...这只是一个总的想法。
if(isset($ _ POST [\'submit \']))
{
$ query = \“ UPDATE tbl SET \”;
if(isset($ _ POST [\'firstname \'])&& $ _POST [\'firstname \']!= \“ \”)$ query。= \“ firstname = \”。$ _ POST [\'firstname \' ];
//执行查询
}
,为什么要将该值留空。您可以在表格中进行描述。如:
<input type=\"text\" name=\"firstname\" values=<?php echo $firstname;?>
并在提交检查为
$query = \"Update table SET \"
if(isset($_POST[\'firstname\']) && strlen($_POST[\'firstname\'])>0){
$query.= \"firstname = \".$_POST[\'variable\'];
}
,如果您在查询中使用$ _POST / $ _ GET,则可以这样构建。
$ _POST的示例:
<?php
$MoreSQL = \'\';
if (trim($_POST[\'username\'] != \'\')) {
$MoreSQL .= \'username=\"\'.trim($_POST[\'username\']).\'\"\';
}
if (trim($_POST[\'password\'] != \'\')) {
if ($MoreSQL)
$MoreSQL .= \',\'; // add comma if $MoreSQL is not empty
$MoreSQL .= \'password=\"\'.trim($_POST[\'password\']).\'\"\';
}
if (trim($_POST[\'firstname\'] != \'\')) {
if ($MoreSQL)
$MoreSQL .= \',\'; // add comma if $MoreSQL is not empty
$MoreSQL .= \'firstname=\"\'.trim($_POST[\'firstname\']).\'\"\';
}
if (trim($_POST[\'lastname\'] != \'\')) {
if ($MoreSQL)
$MoreSQL .= \',\'; // add comma if $MoreSQL is not empty
$MoreSQL .= \'lastname=\"\'.trim($_POST[\'lastname\']).\'\"\';
}
if (!$MoreSQL) { // if everything is empty,no need to fire mysql_query
echo \'nothing to update\';
} else { // otherwise,update the record
mysql_query(\'UPDATE mytable SET \'.$MoreSQL.\' WHERE membersID=\'.($_POST[\'membersID\'] + 0).\'\');
}
?>
希望对您有意义。
,仍然无法正常工作。我尝试了RRStoyanov建议,因为这似乎是最合理的,最终我得出了以下结论:
if (trim($_POST[\'style\'] != \'\')) {
if ($MoreSQL)
$MoreSQL .= \',\'; // add comma if $MoreSQL is not empty
$MoreSQL .= \'css=\"\'.trim($_POST[\'style\']).\'\"\';
}
if (!$MoreSQL) { // if everything is empty,update the record
mysql_query(\"UPDATE ´database SET \'.$MoreSQL.\' WHERE usernamename=\'.$u_name.\'\");
}
在此之前,我使用了:
mysql_query(\“ UPDATE $ tbl_name SET
css = \'$ css \'WHERE username = \'$ u_name \'\“);
这对我来说效果很好,但是由于几个选项都不能为空,因此无法正确更新。如果为空,则用户可能会擦除其用户名或密码。