PHP项目怎么实现验证码功能?

wen PHP项目 9

本文目录导读:

PHP项目怎么实现验证码功能?

  1. GD库图形验证码
  2. 使用第三方库
  3. 短信/邮箱验证码
  4. 高级功能实现
  5. 安全建议
  6. 完整示例代码

我来详细介绍PHP实现验证码功能的几种常见方法。

GD库图形验证码

基本验证码生成

<?php
// captcha.php
session_start();
// 生成随机验证码
$length = 4;
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // 去除容易混淆的字符
$code = '';
for ($i = 0; $i < $length; $i++) {
    $code .= $chars[rand(0, strlen($chars) - 1)];
}
// 存储验证码到Session
$_SESSION['captcha'] = $code;
// 创建图片
$width = 120;
$height = 40;
$image = imagecreatetruecolor($width, $height);
// 设置颜色
$bgColor = imagecolorallocate($image, 255, 255, 255);
$textColor = imagecolorallocate($image, 0, 0, 0);
$lineColor = imagecolorallocate($image, 200, 200, 200);
$pixelColor = imagecolorallocate($image, 150, 150, 150);
// 填充背景
imagefill($image, 0, 0, $bgColor);
// 添加干扰线
for ($i = 0; $i < 5; $i++) {
    imageline($image, rand(0, $width), rand(0, $height), 
              rand(0, $width), rand(0, $height), $lineColor);
}
// 添加干扰点
for ($i = 0; $i < 100; $i++) {
    imagesetpixel($image, rand(0, $width), rand(0, $height), $pixelColor);
}
// 写入文字
$fontSize = 20;
$x = 20;
for ($i = 0; $i < $length; $i++) {
    $angle = rand(-30, 30);
    $y = rand(25, 35);
    imagettftext($image, $fontSize, $angle, $x, $y, $textColor, 
                 'path/to/font.ttf', $code[$i]);
    $x += 20;
}
// 输出图片
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>

HTML显示验证码

<!-- login.html -->
<!DOCTYPE html>
<html>
<head>登录</title>
</head>
<body>
    <form method="post" action="login.php">
        <!-- 其他表单字段 -->
        <div>
            <input type="text" name="captcha" placeholder="验证码" required>
            <img src="captcha.php" id="captchaImage" onclick="refreshCaptcha()">
            <a href="javascript:void(0)" onclick="refreshCaptcha()">换一张</a>
        </div>
        <button type="submit">登录</button>
    </form>
    <script>
    function refreshCaptcha() {
        document.getElementById('captchaImage').src = 'captcha.php?' + Math.random();
    }
    </script>
</body>
</html>

验证码校验

<?php
// login.php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $captcha = strtoupper($_POST['captcha']);
    if ($captcha === $_SESSION['captcha']) {
        // 验证成功
        echo "验证码正确,登录成功!";
        // 清除验证码(防止重复使用)
        unset($_SESSION['captcha']);
    } else {
        echo "验证码错误,请重新输入!";
    }
}
?>

使用第三方库

Gregwar/Captcha库

composer require gregwar/captcha
<?php
use Gregwar\Captcha\CaptchaBuilder;
session_start();
// 创建验证码
$builder = new CaptchaBuilder;
$builder->build();
// 存储验证码
$_SESSION['phrase'] = $builder->getPhrase();
// 输出图片
header('Content-Type: image/jpeg');
$builder->output();
?>

mewebstudio/captcha库(Laravel常用)

// 安装
composer require mewebstudio/captcha
// 生成验证码
Captcha::create();  // 返回图片信息
// 验证
if (Captcha::check($input)) {
    // 验证通过
}

短信/邮箱验证码

发送验证码接口

<?php
// send_code.php
session_start();
function generateCode($length = 6) {
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= rand(0, 9);
    }
    return $code;
}
// 生成验证码
$code = generateCode();
// 存储验证码和过期时间
$_SESSION['sms_code'] = $code;
$_SESSION['sms_code_time'] = time();
// 发送短信(示例使用阿里云短信)
function sendSMS($phone, $code) {
    // 对接短信服务商API
    // 阿里云、腾讯云、七牛云等
}
// 发送邮箱验证码
function sendEmail($email, $code) {
    // 使用PHPMailer等库发送邮件
}
// 根据场景调用
$type = $_POST['type']; // sms或email
$target = $_POST['target']; // 手机号或邮箱
if ($type === 'sms') {
    sendSMS($target, $code);
    echo json_encode(['status' => 'success', 'message' => '验证码已发送']);
} elseif ($type === 'email') {
    sendEmail($target, $code);
    echo json_encode(['status' => 'success', 'message' => '验证码已发送']);
}
?>

验证码校验接口

<?php
// verify_code.php
session_start();
$inputCode = $_POST['code'];
$storedCode = $_SESSION['sms_code'];
$storedTime = $_SESSION['sms_code_time'];
// 检查验证码是否匹配
if ($inputCode === $storedCode) {
    // 检查是否过期(例如5分钟)
    if (time() - $storedTime <= 300) {
        echo json_encode(['status' => 'success', 'message' => '验证成功']);
        // 清除验证码
        unset($_SESSION['sms_code']);
        unset($_SESSION['sms_code_time']);
    } else {
        echo json_encode(['status' => 'error', 'message' => '验证码已过期']);
    }
} else {
    echo json_encode(['status' => 'error', 'message' => '验证码错误']);
}
?>

高级功能实现

验证码频率限制

<?php
session_start();
function checkRateLimit($key, $maxAttempts = 5, $timeWindow = 300) {
    $now = time();
    $attempts = $_SESSION[$key] ?? [];
    // 清理过期记录
    $attempts = array_filter($attempts, function($time) use ($now) {
        return $now - $time <= $timeWindow;
    });
    if (count($attempts) >= $maxAttempts) {
        return false; // 超过限制
    }
    $attempts[] = $now;
    $_SESSION[$key] = $attempts;
    return true;
}
// 使用
if (!checkRateLimit('captcha_attempts')) {
    die('请求过于频繁,请稍后再试');
}
?>

多次输入错误后锁定

<?php
session_start();
function checkLoginAttempts($username) {
    $key = 'login_attempts_' . $username;
    $attempts = $_SESSION[$key] ?? ['count' => 0, 'lock_time' => 0];
    if ($attempts['lock_time'] > time()) {
        return false; // 账户被锁定
    }
    if ($attempts['count'] >= 3) {
        $attempts['lock_time'] = time() + 300; // 锁定5分钟
        $_SESSION[$key] = $attempts;
        return false;
    }
    return true;
}
function incrementAttempts($username) {
    $key = 'login_attempts_' . $username;
    $attempts = $_SESSION[$key] ?? ['count' => 0, 'lock_time' => 0];
    $attempts['count']++;
    $_SESSION[$key] = $attempts;
}
function resetAttempts($username) {
    $key = 'login_attempts_' . $username;
    unset($_SESSION[$key]);
}
?>

安全建议

  1. 使用HTTPS:防止验证码在传输过程中被截获
  2. 验证码时效性:设置合理的过期时间(通常5-10分钟)
  3. 一次性使用:验证成功后立即清除
  4. 图形干扰:添加噪点、干扰线、扭曲等
  5. 大小写处理:通常不区分大小写
  6. 频率限制:防止暴力破解
  7. 避免使用简单字符:如0和O、1和I等

完整示例代码

<?php
// 完整的验证码类
class Captcha {
    private $width = 120;
    private $height = 40;
    private $length = 4;
    private $characters = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
    public function generate() {
        session_start();
        // 生成验证码
        $code = '';
        for ($i = 0; $i < $this->length; $i++) {
            $code .= $this->characters[rand(0, strlen($this->characters) - 1)];
        }
        $_SESSION['captcha'] = $code;
        $_SESSION['captcha_time'] = time();
        return $code;
    }
    public function output() {
        $code = $this->generate();
        $image = imagecreatetruecolor($this->width, $this->height);
        // 设置颜色
        $bgColor = imagecolorallocate($image, 255, 255, 255);
        $textColor = imagecolorallocate($image, 0, 0, 0);
        $lineColor = imagecolorallocate($image, 200, 200, 200);
        imagefill($image, 0, 0, $bgColor);
        // 添加干扰线
        for ($i = 0; $i < 5; $i++) {
            imageline($image, rand(0, $this->width), rand(0, $this->height),
                      rand(0, $this->width), rand(0, $this->height), $lineColor);
        }
        // 写入文字
        $fontSize = 20;
        $x = 20;
        for ($i = 0; $i < $this->length; $i++) {
            imagestring($image, $fontSize, $x, rand(10, 20), $code[$i], $textColor);
            $x += 20;
        }
        header('Content-Type: image/png');
        imagepng($image);
        imagedestroy($image);
    }
    public function verify($input, $caseInsensitive = true) {
        session_start();
        if (!isset($_SESSION['captcha'])) {
            return false;
        }
        // 检查是否过期(5分钟)
        if (time() - $_SESSION['captcha_time'] > 300) {
            unset($_SESSION['captcha']);
            return false;
        }
        $stored = $_SESSION['captcha'];
        if ($caseInsensitive) {
            $input = strtoupper($input);
        }
        $result = $input === $stored;
        // 清除验证码
        unset($_SESSION['captcha']);
        unset($_SESSION['captcha_time']);
        return $result;
    }
}
// 使用示例
$captcha = new Captcha();
$captcha->output(); // 生成验证码图片
// 验证
if ($captcha->verify($_POST['captcha'])) {
    echo "验证成功";
} else {
    echo "验证失败";
}
?>

这些方法涵盖了从基础的图形验证码到高级的短信/邮箱验证码实现,你可以根据项目需求选择合适的方案。

抱歉,评论功能暂时关闭!