Php 更新表记录,而不是添加新记录

Php 更新表记录,而不是添加新记录,php,mysql,Php,Mysql,好的。。事情是这样的。我想列出已登录的用户,并在注销时更改其状态。这很好用。我创建了一个名为tblaudit_users的表。我从tbl_用户表中选择的现有用户 我想要的是,如果tblaudit_users表中已经存在一个用户,那么它将使用NOW()更新LastTimeSeen时间。但它不是更新该记录,而是创建一个新记录。这样桌子会越来越大,我想避免这种情况。我为此使用的代码如下所示: +++++++++++++++++++ $ipaddress = $_SERVER['REMOTE_ADDR'

好的。。事情是这样的。我想列出已登录的用户,并在注销时更改其状态。这很好用。我创建了一个名为tblaudit_users的表。我从tbl_用户表中选择的现有用户

我想要的是,如果tblaudit_users表中已经存在一个用户,那么它将使用NOW()更新LastTimeSeen时间。但它不是更新该记录,而是创建一个新记录。这样桌子会越来越大,我想避免这种情况。我为此使用的代码如下所示:

+++++++++++++++++++

$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();
    }
}