Php 更新表记录,而不是添加新记录
好的。。事情是这样的。我想列出已登录的用户,并在注销时更改其状态。这很好用。我创建了一个名为tblaudit_users的表。我从tbl_用户表中选择的现有用户 我想要的是,如果tblaudit_users表中已经存在一个用户,那么它将使用NOW()更新LastTimeSeen时间。但它不是更新该记录,而是创建一个新记录。这样桌子会越来越大,我想避免这种情况。我为此使用的代码如下所示: +++++++++++++++++++Php 更新表记录,而不是添加新记录,php,mysql,Php,Mysql,好的。。事情是这样的。我想列出已登录的用户,并在注销时更改其状态。这很好用。我创建了一个名为tblaudit_users的表。我从tbl_用户表中选择的现有用户 我想要的是,如果tblaudit_users表中已经存在一个用户,那么它将使用NOW()更新LastTimeSeen时间。但它不是更新该记录,而是创建一个新记录。这样桌子会越来越大,我想避免这种情况。我为此使用的代码如下所示: +++++++++++++++++++ $ipaddress = $_SERVER['REMOTE_ADDR'
$ipaddress = $_SERVER['REMOTE_ADDR'];
if(isset($_SESSION['id'])){
$userId = $_SESSION['id'];
$username = $_SESSION['username'];
$achternaam = $_SESSION['achternaam'];
$district = $_SESSION['district'];
$gemeente = $_SESSION['gemeente'];
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' AND active = '1' LIMIT 1");
$query->execute();
foreach($query->fetchAll(PDO::FETCH_OBJ) as $value){
$duplicate = $value->username;
}
if($duplicate != 1){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
");
$insert->execute();
} elseif($duplicate = 1){
$update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE username = '{$username}'");
$update->execute();
} else {
header('Location: index.php');
die();
}
}
我迷路了,搜索了很多网站/页面来解决这个问题,希望这里有人能帮助我?提前谢谢
更新:
我试过下面的方法,但没有结果
+++++
嗯。我稍微修改了我的查询和代码:
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' LIMIT 1");
$query->execute();
if($query){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
ON DUPLICATE KEY UPDATE set LastTimeSeen = NOW(), status = '1'
");
$insert->execute();
} else {
header('Location: index.php');
die();
}
}
我还添加了一个名为pid(主id)的唯一键。仍然不工作。基于,在更新语法中不要使用“set”
页面中的示例:
INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;
几个问题:
- 您在
上进行测试,但这是您的语句对象,即使您没有从$query
语句返回任何记录,它也将有效李>select
- 在确保前一条语句已关闭或至少已获取其所有记录之前,访问第二条准备好的语句可能会出现问题李>
语句中存在语法错误(insert
不应存在)李>set
- 对于
时,您提供的值必须包括唯一密钥李>插入。。。重复密钥更新
- SQL注入漏洞李>
和select
的不必要拆分:这可以在一条语句中完成insert
$query = $db->prepare("SELECT * FROM tblaudit_users
WHERE username = '{$username}' LIMIT 1");
$query->execute();
$query->store_result();
if($query->num_rows()){
$query->close();
// etc...
但是,当您执行insert。。。在重复密钥更新时
:无需首先使用检查并选择
该用户是否确实存在。这一切都是由insert。。。在重复密钥更新时
语句
插入时出错
重复键更新时的语法不应在其后面设置一词
防止SQL注入
尽管您使用准备好的语句(好!),但仍然将字符串注入到SQL语句中(坏!)。预处理语句的优点之一是,您可以使用以下参数对查询使用参数,而无需实际将字符串注入SQL字符串:
这样你就避免了
确保user_uid
在tb劳dit\u users
中具有唯一约束。将另一个(自动增量)字段作为主键没有帮助。它必须是要为其插入值的字段之一
上述代码不再使用$query
。你不需要它。我发现了问题
if(isset($_SESSION['id'])){
$userId = $_SESSION['id'];
$username = $_SESSION['username'];
$achternaam = $_SESSION['achternaam'];
$district = $_SESSION['district'];
$gemeente = $_SESSION['gemeente'];
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE user_id = '{$userId}' LIMIT 1");
$query->execute();
if($query->rowcount()<1){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
");
$insert->execute();
} elseif($query->rowcount()>0) {
$update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE user_id = '{$userId}'");
$update->execute();
} else {
header('Location: index.php');
die();
}
}
if(isset($\u会话['id'])){
$userId=$\会话['id'];
$username=$\会话['username'];
$achternaam=$\会话['achternaam'];
$district=$_SESSION['district'];
$gemeente=$_会话['gemeente'];
$query=$db->prepare(“从tblaudit_用户中选择*,其中用户id='{$userId}'限制1”);
$query->execute();
如果($query->rowcount()准备(“
插入tblaudit_用户(用户id、用户名、achternaam、地区、gemeente、ipaddress、LastTimeSeen、状态)
值({$userId}、{$username}、{$achternaam}、{$district}、{$gemeente}、{$ipaddress}、NOW()、'1'))
");
$insert->execute();
}elseif($query->rowcount()>0){
$update=$db->prepare(“update tblaudit_users SET LastTimeSeen=NOW(),status='1',其中user_id='{$userId}'”;
$update->execute();
}否则{
标题('Location:index.php');
模具();
}
}
在我的查询中没有使用$username,而是选择$userId,这样就可以了。您是否尝试过MySQL语句语法INSERT…ON DUPLICATE KEY UPDATE
?如果没有,请尝试一下。如果是,请回答您的问题,以显示您的答案tried@David:我已经试过了,但不起作用。还从$query中删除了一些WHERE子句。WHERE active='1'不是表中的一列。tblaudit_用户
是否有主键/唯一键?它似乎找不到带有$username的记录。我猜我的'if'语句是错误的,但无法找出为什么将userid设置为键?您仍然容易受到SQL注入的攻击,如果两个用户执行此sc,您的代码将有一天失败同时(并发性)@trincot:你能解释一下SQL注入的漏洞在哪里,以及如果两个用户执行此脚本为什么会失败吗?谢谢你在这里将会话变量如gemeente
直接插入到insert
语句中。由于这些变量在用户定义的某个点上,它们可能包含恶意代码,这将改变mSQL语句的eaning。了解SQL注入。如果两个用户几乎同时执行脚本,并且在其会话中都具有相同的用户id(例如,如果我使用两个浏览器窗口),则两个都无法从第一个选择,然后插入两个具有相同用户id值的记录,这不是您想要的。
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district,
gemeente, ipaddress, LastTimeSeen, status)
VALUES (?, ?, ?, ?, ?, ?, NOW(), '1')
ON DUPLICATE KEY UPDATE LastTimeSeen = NOW(), status = '1'
");
$insert->bind_param("ssssss", $userId, $username, $achternaam,
$district, $gemeente, $ipaddress);
$insert->execute();
if(isset($_SESSION['id'])){
$userId = $_SESSION['id'];
$username = $_SESSION['username'];
$achternaam = $_SESSION['achternaam'];
$district = $_SESSION['district'];
$gemeente = $_SESSION['gemeente'];
$query = $db->prepare("SELECT * FROM tblaudit_users WHERE user_id = '{$userId}' LIMIT 1");
$query->execute();
if($query->rowcount()<1){
$insert = $db->prepare("
INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
");
$insert->execute();
} elseif($query->rowcount()>0) {
$update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE user_id = '{$userId}'");
$update->execute();
} else {
header('Location: index.php');
die();
}
}