PHP MYSQL INTERVAL显示剩下多少时间?

时间:2013-07-04 14:20:11

标签: php mysql

基本上,我有一个带阻塞系统的登录系统。 阻止用户使用超过5次尝试,如果他仍然尝试,尝试次数将增加。

要删除它,我这样做:

"DELETE FROM login_attempts WHERE date < DATE_SUB(NOW(), INTERVAL :time) AND ip_address = :ip"

:时间=间隔日期

示例:

            if ($fetch['attempts'] < 6)
            {
                $time = "10 MINUTE";
            } 
            else if ($fetch['attempts'] < 10) 
            {
                $time = "1 HOUR";
            }
            else if ($fetch['attempts'] < 21)
            {
                $time = "1 DAY";
            }
            else if ($fetch['attempts'] > 21)
            {
                $time = "14 DAY";
            }

基本上我想要做的是,我需要找出,如何告诉玩家他何时会被解锁。

如果我知道他将被解锁的时间量,我怎么能回应时间直到他被解锁?我不想只是回应日期,我需要确切地回复多少天,几小时等等。

我从来没有这样做过,我现在陷入困境。

2 个答案:

答案 0 :(得分:2)

您写道:“这些失败将在1天后重置”。然后,不可能达到超过21次失败的尝试,因为在第21次尝试失败时,该帐户被锁定了一天。

我认为你应该只在成功尝试时重置计数器。

话虽如此,让我们回到你的实际问题。您正试图显示该帐户将保持锁定的时间。

我会采取相反的方法:根据失败的尝试次数,计算帐户解锁的日期,然后计算此日期之前的剩余时间。

第1步:尝试失败次数

SELECT COUNT(*) AS failed_count
FROM login_attempts WHERE account_id = :account AND ip_address = :ip

步骤2:解锁的日期/时间,基于失败尝试次数

纯SQL中的解决方案:

SELECT
    CASE
        WHEN COUNT(*) <= 5 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 10 MINUTE)
        WHEN COUNT(*) <= 10 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 HOUR)
        WHEN COUNT(*) <= 20 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 DAY)
        ELSE DATE_ADD(MAX(date_of_attempt), INTERVAL 14 DAY)
    END AS unlock_date
FROM login_attempts WHERE account_id = :account AND ip_address = :ip

注意:我将根据您将在应用程序层中维护的规则,从PHP动态构建上述查询。但是坚持这个查询,因为你在一个查询中得到了所有内容,并且如果你有适当的索引它几乎立即运行。

第3步:解锁日期/时间

多长时间

要么在PHP中计算(应该是微不足道的),要么直接在MySQL中计算:

SELECT
    TIMEDIFF(
        NOW(),
        CASE
            WHEN COUNT(*) <= 5 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 10 MINUTE)
            WHEN COUNT(*) <= 10 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 HOUR)
            WHEN COUNT(*) <= 20 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 DAY)
            ELSE DATE_ADD(MAX(date_of_attempt), INTERVAL 14 DAY)
        END          
    ) AS time_remaining_in_hours
FROM login_attempts WHERE account_id = :account AND ip_address = :ip

答案 1 :(得分:-2)