基本上,我有一个带有阻塞系统的登录系统。 如果用户尝试次数超过 5 次,则阻止,如果他仍将尝试,则尝试次数会增加。
要删除它,我这样做:
"DELETE FROM login_attempts WHERE date < DATE_SUB(NOW(), INTERVAL :time) AND ip_address = :ip"
:time = 间隔日期
例子:
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";
}
基本上我想做的是,我需要找出如何告诉玩家他什么时候可以解锁。
如果我知道他将被解锁的时间量,我如何回显他被解锁的时间?我不想只回显日期,我需要准确回显多少天、几小时等。
我从来没有这样做过,我被困在这一点上。
最佳答案
您写道:“这些失败将在 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
关于PHP MYSQL INTERVAL 显示还剩多少时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17472656/