php实现登录次数
PHP 实现登录次数限制的方法
使用 Session 记录登录尝试次数
在用户登录失败时,通过 Session 记录尝试次数。超过限制后阻止登录。
session_start();
$max_attempts = 3;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!isset($_SESSION['login_attempts'])) {
$_SESSION['login_attempts'] = 0;
}
if ($_SESSION['login_attempts'] >= $max_attempts) {
die('登录尝试次数过多,请稍后再试');
}
// 验证用户名密码
if ($username != 'correct_user' || $password != 'correct_pass') {
$_SESSION['login_attempts']++;
echo '用户名或密码错误,剩余尝试次数: ' . ($max_attempts - $_SESSION['login_attempts']);
} else {
// 登录成功,重置尝试次数
unset($_SESSION['login_attempts']);
// 继续登录流程
}
}
使用数据库记录登录尝试
对于更持久化的记录,可以使用数据库存储登录尝试次数。
// 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'username', 'password');
// 检查登录尝试
$stmt = $pdo->prepare("SELECT attempts, last_attempt FROM login_attempts WHERE ip = ?");
$stmt->execute([$_SERVER['REMOTE_ADDR']]);
$attempt = $stmt->fetch();
$max_attempts = 5;
$lockout_time = 15 * 60; // 15分钟
if ($attempt && $attempt['attempts'] >= $max_attempts) {
if (time() - strtotime($attempt['last_attempt']) < $lockout_time) {
die('账号已锁定,请稍后再试');
} else {
// 锁定时间已过,重置尝试
$pdo->prepare("UPDATE login_attempts SET attempts = 0 WHERE ip = ?")->execute([$_SERVER['REMOTE_ADDR']]);
}
}
// 验证登录
if ($login_failed) {
if ($attempt) {
$pdo->prepare("UPDATE login_attempts SET attempts = attempts + 1, last_attempt = NOW() WHERE ip = ?")->execute([$_SERVER['REMOTE_ADDR']]);
} else {
$pdo->prepare("INSERT INTO login_attempts (ip, attempts) VALUES (?, 1)")->execute([$_SERVER['REMOTE_ADDR']]);
}
}
使用 Cookie 实现客户端限制
结合 Cookie 实现客户端登录次数限制。
$cookie_name = 'login_attempts';
$max_attempts = 3;
if (isset($_COOKIE[$cookie_name]) && $_COOKIE[$cookie_name] >= $max_attempts) {
die('登录尝试次数过多');
}
if ($login_failed) {
$attempts = isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] + 1 : 1;
setcookie($cookie_name, $attempts, time() + 3600); // 1小时有效期
}
完整登录限制类示例
封装一个完整的登录限制类,包含多种限制方式。

class LoginLimiter {
private $max_attempts = 5;
private $lockout_time = 900; // 15分钟
public function checkAttempts($identifier) {
$attempt = $this->getAttemptRecord($identifier);
if ($attempt && $attempt['attempts'] >= $this->max_attempts) {
if (time() - strtotime($attempt['last_attempt']) < $this->lockout_time) {
return false;
}
$this->resetAttempts($identifier);
}
return true;
}
public function recordFailure($identifier) {
$this->incrementAttempts($identifier);
}
public function recordSuccess($identifier) {
$this->resetAttempts($identifier);
}
// 其他私有方法实现数据库操作...
}
安全注意事项
- 对于重要系统,建议结合多种限制方式
- 考虑使用验证码在多次失败后显示
- 记录登录尝试日志用于安全审计
- 防止暴力破解时,限制请求频率比单纯计数更有效
以上方法可以根据实际需求组合使用,提供不同级别的登录保护。数据库方式更可靠但需要额外存储,Session方式简单但只在会话期间有效。






