PHP 使用 GD 库绘制登录页图片验证码

Ryan
Ryan
发布时间:2026-10-13 | 4人浏览过
原创

本文介绍如何使用 PHP 结合 GD 库生成图像验证码,通过将随机生成的字母数字组合绘制为图片并在 HTML 表单中展示,有效防范垃圾账号注册和自动化脚本的攻击。

验证码原理与作用

登录页面的验证码是一种基础的安全防护机制。它要求用户在提交数据前进行视觉识别操作,能够有效区分人类用户与自动化脚本(如注册机)。这可以防止程序批量创建虚假账号占用服务器资源,保障系统稳定运行。

一张标准的图片验证码通常包含以下要素:

  • 随机文本:从指定字符集中抽取固定数量的字符。
  • 背景与干扰:添加随机颜色背景、干扰线或噪点以增加机器识别难度。
  • 格式输出:将上述内容渲染为 PNG 或 JPG 格式的图像流。

前端页面集成

前端需要构建一个简单的 HTML 表单,并通过 <img> 标签引用 PHP 脚本生成的验证码图片。点击刷新链接时,可通过拼接时间戳参数强制浏览器重新请求图片。

  1. 创建 HTML 文件,包含用户名、密码输入框及验证码输入框。
  2. 插入 <img> 标签指向后端验证码生成脚本(如 libs/verification.php)。
  3. 编写 JavaScript 函数,在点击事件中将图片 src 追加随机数后缀以刷新。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>测试页面</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
</head>
<body>
<form name="form" action="#" method="post">
    <input type="text" placeholder="账号" required /><br/>
    <input type="password" placeholder="密码" required /><br/>
    <input type="text" placeholder="验证码" required />
    <img id="verImg" src="libs/verification.php" style="cursor:pointer;" onclick="changeVer()" title="看不清?点击换一张"/>
    <a href="javascript:void(0)" class="change" onclick="changeVer()">点击刷新</a><br/>
    <input type="submit" value="登录"/>
</form>
<script type="text/javascript">
function changeVer(){
    document.getElementById("verImg").src="libs/verification.php?tmp="+Math.random();
}
</script>
</body>
</html>

生成的验证码样式如下:

用户点击“点击刷新”后,会更新验证码:

后端生成逻辑

PHP 脚本负责读取会话数据(若存在),生成随机字符串,利用 PHP 内置的 GD 图像处理函数绘制画布,并输出图像响应。以下是核心代码结构:

第 1 步:初始化环境

开启 session 以便存储当前验证码文本供后续校验;定义绘图函数 vCode(),设置默认字符数为 4,字体大小为 20。

<?php
session_start();
vCode(4); // 调用默认参数:4位字符

第 2 步:构建字符集与随机文本

为避免视觉混淆,剔除容易看错的字符(如 0/O, 1/l/I)。循环取出规定数量的字符存入 $code 变量。

// 设置验证码字符集合,去除了易混淆字符
$str = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVW";
$code = '';
for ($i = 0; $i < $num; $i++) {
    $code .= $str[mt_rand(0, strlen($str)-1)];
}

第 3 步:绘制图像背景与干扰项

根据字符数量和字体大小计算画布宽度和高度。分配随机颜色的背景矩形,并绘制多条弧线(模拟干扰线)和散乱像素点(噪点)。

// 创建画布
$im = imagecreatetruecolor($width, $height);
// 设置背景色
$back_color = imagecolorallocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
imagefilledrectangle($im, 0, 0, $width, $height, $back_color);

// 画干扰线 (5条)
for($i = 0; $i < 5; $i++) {
    $font_color = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
    imagearc($im, mt_rand(- $width, $width), mt_rand(- $height, $height), 
             mt_rand(30, $width * 2), mt_rand(20, $height * 2), 
             mt_rand(0, 360), mt_rand(0, 360), $font_color);
}

// 画干扰点 (50个)
for($i = 0; $i < 50; $i++) {
    $font_color = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
    imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $font_color);
}

第 4 步:渲染文字并输出

选择一种本地 TTF 字体文件(示例中为宋体 simsun.ttc),设置随机旋转角度,将 $code 写入画布。最后输出 HTTP 头信息并以 PNG 格式发送图像,清理内存。

// 随机旋转角度
$array = array(5,4,3,2,1,0,-1,-2,-3,-4,-5);
// 输出验证码文字 -x,y坐标根据具体字体调整可能需要微调
ttf_extents = imagettfbbox($size, 0, 'c:/WINDOWS/Fonts/simsun.ttc', $code);
// 注意:原文代码使用 imagefttext 且位置相对写死,生产环境建议根据字数动态居中
@imagefttext($im, $size, array_rand($array), 12, $size + 6, $text_color, 'c:\WINDOWS\Fonts\simsun.ttc', $code);

$_SESSION["VerifyCode"] = $code;
header("Cache-Control: no-cache");
header("Content-type: image/png;charset=gb2312");
imagepng($im);
imagedestroy($im);

以上就是使用 PHP 绘制网站登录首页图片验证码的详细内容,更多关于 PHP 验证码开发的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表