MYSQL行没有正确递增

时间:2015-01-08 23:26:40

标签: php mysql

我正在创建一段代码,在24小时内尝试使用错误的密码登录5次后,会阻止用户48小时。如果用户在24小时内成功登录,则应重置尝试次数。

我有ATM的问题是尝试计数,如果我尝试更多次,它只更新该用户的第一行。这是最近发生的一个例子:

  • 用户 - 时间 - 尝试 - 计数()
  • 用户1 10:00 pm尝试1(5)
  • 用户1 10:02 pm尝试2(4)
  • 用户1 10:04 pm尝试3(3)
  • 用户1 10:06 pm尝试4(2)
  • 用户1 10:07 pm尝试5(1)
  • 用户2 10:15 pm尝试1(2)
  • 用户2 10:20 pm尝试2(1)

如您所见,所有尝试都将增加(括号中的数字),但最新的尝试将设置为1。如何获得它以便所有尝试都增加,所以它看起来像这样。

  • 用户 - 时间 - 尝试 - 计数()
  • 用户1 10:00 pm尝试1(5)
  • 用户1 10:02 pm尝试2(5)
  • 用户1 10:04 pm尝试3(5)
  • 用户1 10:06 pm尝试4(5)
  • 用户1 10:07 pm尝试5(5)
  • 用户2 10:15 pm尝试1(2)
  • 用户2 10:20 pm尝试2(2)

以下是我的代码片段:

if (!$pw_ok)    {
            if (isset($_SERVER["REMOTE_ADDR"])) {
                    $str_RemoteHost = $_SERVER["REMOTE_ADDR"];
                } else {
                    $str_RemoteHost = '';
                }
        $qry_WriteToDatabase = "INSERT INTO cms_user_login_attempts
                                (
                                    cula_user_id,
                                    cula_date_time,
                                    cula_remote_host,
                                    cula_attempt_count
                                )
                        VALUES      (
                                    " . $db->SQLString($row->user_id) . ",
                                    Now(),
                                    " . $db->SQLString($str_RemoteHost, true) . ",
                                    'cula_attempt_count'
                                    )";
        $db->query($qry_WriteToDatabase);

        $qry_UpdateCount = "UPDATE 
                                cms_user_login_attempts
                            SET 
                                cula_attempt_count = cula_attempt_count + 1
                            WHERE 
                                cula_user_id = " . $db->SQLString($row->user_id) . " ";
        $db->query($qry_UpdateCount);                           

        $qry_CheckDatabase = "  SELECT 
                                    CASE WHEN count(*) >= 5 THEN 0 ELSE 1 END as allowed_login 
                                FROM
                                    cms_user_login_attempts
                                WHERE
                                    cula_date_time >= DATE_SUB(CURRENT_TIMESTAMP, interval 48 hour) 
                                AND 
                                    cula_user_id = " . $db->SQLString($row->user_id) . "";
            $rs_CheckDatabase = $db->query($qry_CheckDatabase);

            if (! (isset($qry_CheckDatabase) && $qry_CheckDatabase)) {
            $errors->defineError("invalid_user_pass", "Too many attempts, account locked for 48hours.", array("username","password"));
            }
    }

2 个答案:

答案 0 :(得分:1)

要将cula_attempt_count设置为尝试的总和,您需要执行子查询以获得总和,即

UPDATE cms_user_login_attempts 
SET cula_attempt_count = (
    SELECT COUNT(*)
    FROM cms_user_login_attempts
    WHERE cula_user_id = $db->SQLString($row->user_id)
    AND cula_date_time > DATE_SUB(NOW(), INTERVAL 24 HOUR))
WHERE  cula_user_id = $db->SQLString($row->user_id)
AND cula_date_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)

您需要嵌套内部查询,因此将其视为tmp表

UPDATE cms_user_login_attempts 
SET cula_attempt_count = (
  SELECT * FROM (
    SELECT COUNT(*) as `sum`
    FROM cms_user_login_attempts
    WHERE cula_user_id = $db->SQLString($row->user_id)
    AND cula_date_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)
  )
)
WHERE  cula_user_id = $db->SQLString($row->user_id)
AND cula_date_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)

答案 1 :(得分:0)

在新记录的insert语句中,您尝试将cula_attempt_count的值设置为字符串:'cula_attempt_count'

这是数字字段的无效值,因此MySQL将字段的值设置为0,然后在下一个查询时将其增加到1

要执行您要执行的操作,您需要在插件中添加子查询,如下所示:

"INSERT INTO cms_user_login_attempts (ula_user_id, cula_date_time, cula_remote_host, cula_attempt_count )
VALUES (" . $db->SQLString($row->user_id) . ",
        Now(),
        " . $db->SQLString($str_RemoteHost, true) . ",
        IFNULL((SELECT cula_attempt_count FROM cms_login_attempts
            WHERE ula_user_id=" . $db->SQLString($row->user_id) . "
            AND cula_date_time >= DATE_SUB(CURRENT_TIMESTAMP, interval 48 hour)
            ORDER BY cula_date_time DESC LIMIT 1), 0))"

此子查询将在48小时内从用户上次登录尝试返回cula_attempt_countIFNULL用于处理用户在过去48小时内未登录的情况,因此返回0。