php技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > PHP编程 > php技巧 > PHP图像验证码

使用PHP创建图像验证码的示例代码

作者:我叫黑大帅

PHP 图像验证码的实现完全基于GD 库,它是 PHP 官方内置的图像处理扩展,提供了画布创建、颜色分配、文本绘制、图形渲染、图片输出等全能力,下面小编就和大家详细介绍一下具体如何实现的吧

PHP 图像验证码的实现完全基于GD 库,它是 PHP 官方内置的图像处理扩展,提供了画布创建、颜色分配、文本绘制、图形渲染、图片输出等全能力,是 PHP 图像处理的行业标准方案。

开启 GD 扩展

生成验证码

第一步:开启Session与配置

<?php
// 开启Session,用于存储验证码校验值(必须在输出前执行,无任何前置空格)
session_start();
// 引入验证码配置
$captchaConfig = [
    // 基础尺寸配置
    'width'       => 150,         // 验证码图片宽度
    'height'      => 50,          // 验证码图片高度
    // 字符配置
    'length'      => 4,           // 验证码字符长度,常用4-6位
    'charset'     => '23456789ABCDEFGHJKLMNPQRSTUVWXYZ', // 字符集:去掉易混淆的0/O、1/l,提升用户体验
    'font_size'   => 24,          // 字体字号
    'font_file'   => './fonts/arial.ttf', // TTF字体文件路径,必须填写正确,否则无法绘制文字
    // 干扰项配置(平衡安全性与识别度)
    'line_num'    => 6,           // 干扰线数量
    'pixel_num'   => 100,         // 噪点数量
    // 安全配置
    'expire'      => 300,         // 验证码有效期,单位秒,默认5分钟
    'session_key' => 'captcha_code', // Session存储的key
];

第二步:创建画布+分配基础颜色

// 创建真彩色画布
$img = imagecreatetruecolor($captchaConfig['width'], $captchaConfig['height']);
// 分配背景色:浅色系背景,提升文字辨识度(240-255区间)
$bgColor = imagecolorallocate($img, 245, 245, 245);
// 分配文字颜色:深色系,随机生成避免固定色值被OCR识别
$textColor = imagecolorallocate($img, rand(10, 50), rand(10, 50), rand(10, 50));
// 填充画布背景
imagefill($img, 0, 0, $bgColor);
API 函数核心作用
imagecreatetruecolor(int $width, int $height)创建真彩色的图像画布,是验证码的载体
imagecolorallocate(resource $image, int $red, int $green, int $blue)为画布分配 RGB 颜色,用于背景、文字、干扰项绘制
imagefill(resource $image, int $x, int $y, int $color)为画布填充背景色,从坐标 (x,y) 开始填充

第三步:生成随机验证码字符串

$code = '';
$charsetLen = strlen($captchaConfig['charset']);
for ($i = 0; $i < $captchaConfig['length']; $i++) {
    // 从字符集中随机取一个字符,拼接成最终验证码
    $code .= $captchaConfig['charset'][rand(0, $charsetLen - 1)];
}

第四步:绘制干扰元素(先画干扰项,再画文字,避免文字被遮挡)

// 绘制随机干扰线
for ($i = 0; $i < $captchaConfig['line_num']; $i++) {
    // 随机生成线条颜色(浅色系,不抢文字视觉)
    $lineColor = imagecolorallocate($img, rand(100, 200), rand(100, 200), rand(100, 200));
    // 随机生成线条起点和终点,贯穿整个画布
    imageline(
        $img,
        rand(0, $captchaConfig['width']),
        rand(0, $captchaConfig['height']),
        rand(0, $captchaConfig['width']),
        rand(0, $captchaConfig['height']),
        $lineColor
    );
}
// 绘制随机噪点
for ($i = 0; $i < $captchaConfig['pixel_num']; $i++) {
    // 随机生成噪点颜色
    $pixelColor = imagecolorallocate($img, rand(50, 150), rand(50, 150), rand(50, 150));
    // 随机生成噪点位置
    imagesetpixel($img, rand(0, $captchaConfig['width']), rand(0, $captchaConfig['height']), $pixelColor);
}

第五步:绘制验证码字符到画布

// 计算单个字符的宽度,均匀分布在画布上
$singleWidth = $captchaConfig['width'] / $captchaConfig['length'];
for ($i = 0; $i < $captchaConfig['length']; $i++) {
    // 每个字符随机旋转-10到10度,防止机器识别
    $angle = rand(-10, 10);
    // 计算字符的x坐标,左右留边距,均匀分布
    $x = $singleWidth * $i + rand(5, 10);
    // 计算字符的y坐标,垂直居中(基线对齐,避免文字下沉)
    $y = $captchaConfig['height'] / 2 + $captchaConfig['font_size'] / 3;
    // 写入单个字符到画布
    imagettftext(
        $img,
        $captchaConfig['font_size'],
        $angle,
        $x,
        $y,
        $textColor,
        $captchaConfig['font_file'],
        $code[$i]
    );
}

imagettftext(resource $image, float $size, float $angle, int $x, int $y, int $color, string $font_file, string $text)写入 TrueType 字体文本,是绘制验证码字符的核心,支持自定义字体、字号、文字旋转角度

第六步:存储验证码到Session,完成服务端持久化

// 存储加密后的验证码+过期时间,生产环境建议加密存储,避免Session泄露
$_SESSION[$captchaConfig['session_key']] = [
    'code' => strtolower($code), // 转小写,实现不区分大小写校验,提升用户体验
    'expire_time' => time() + $captchaConfig['expire'] // 过期时间戳
];

第七步:输出图片到浏览器

// 声明响应头为PNG图片,禁止浏览器缓存
header('Content-Type: image/png');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
// 输出图片
imagepng($img);
// 销毁画布资源,释放内存
imagedestroy($img);

校验验证码

<?php
// 1. 开启Session,与生成端保持一致
session_start();
// 2. 配置项,必须与生成端保持一致
$captchaConfig = [
    'session_key' => 'captcha_code',
];
// 3. 封装校验函数,可全局复用
function checkCaptcha(string $userInput): array
{
    global $captchaConfig;
    // 3.1 先判断用户是否输入了验证码
    if (empty($userInput)) {
        return ['status' => false, 'msg' => '请输入验证码'];
    }
    // 3.2 判断服务端是否存在验证码Session
    if (!isset($_SESSION[$captchaConfig['session_key']])) {
        return ['status' => false, 'msg' => '验证码已过期,请刷新重试'];
    }
    // 3.3 取出Session中的验证码数据
    $captchaData = $_SESSION[$captchaConfig['session_key']];
    // 3.4 校验验证码是否过期
    if (time() > $captchaData['expire_time']) {
        // 过期后立即销毁,防止复用
        unset($_SESSION[$captchaConfig['session_key']]);
        return ['status' => false, 'msg' => '验证码已过期,请刷新重试'];
    }
    // 3.5 校验验证码是否正确(统一转小写,不区分大小写)
    if (strtolower(trim($userInput)) !== $captchaData['code']) {
        // 校验失败立即销毁,防止破解
        unset($_SESSION[$captchaConfig['session_key']]);
        return ['status' => false, 'msg' => '验证码错误,请刷新重试'];
    }
    // 3.6 校验成功,立即销毁当前验证码,防止重放攻击(单次有效)
    unset($_SESSION[$captchaConfig['session_key']]);
    return ['status' => true, 'msg' => '验证码校验通过'];
}
// 4. 调用示例(用户POST提交表单时)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 获取用户输入的验证码
    $userCaptcha = $_POST['captcha'] ?? '';
    // 执行校验
    $checkResult = checkCaptcha($userCaptcha);
    if (!$checkResult['status']) {
        // 校验失败,返回错误信息
        echo json_encode(['code' => 400, 'msg' => $checkResult['msg']]);
        exit;
    }
    // 校验通过,执行后续业务逻辑(登录、注册、发送短信等)
    echo json_encode(['code' => 200, 'msg' => '操作成功']);
    exit;
}

生产环境注意事项与安全规范

必须使用 HTTPS 传输:验证码接口和表单提交接口必须通过 HTTPS 传输,防止中间人窃取验证码图片和提交内容,规避重放攻击。

验证码存储安全

用户体验与安全平衡

防破解规范

字体与资源规范

输出规范

严禁存储敏感信息:验证码仅用于人机校验,禁止在其中嵌入用户 ID、密码等敏感信息。

到此这篇关于使用PHP创建图像验证码的示例代码的文章就介绍到这了,更多相关PHP图像验证码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文