导读:本期聚焦于小伙伴创作的《PHP验证码怎么生成?用GD库绘制随机字符和干扰线的实用技巧》,敬请观看详情。不少登录接口被机器批量爆破,根源常是缺少有效人机校验。用PHP自带的GD库能低成本画出验证码:先建画布、填背景色,再写随机字母数字,最后用乱线干扰OCR识别。本文说明如何控制字符间距、线条透明度与扭曲度,使脚本难以自动读取而真人易辨认。我们会给出可直接套用的代码,并解释imagecreatetruecolor、imagettftext等函数的参数含义,以及常见乱码与session丢失的排查思路。

在Web登录或注册页面中,使用PHP结合GD库生成验证码是最基础也最实用的防护手段之一。通过随机字符配合干扰线,可以有效阻挡大部分简单的自动提交脚本。下面直接看一段可运行的完整示例,再逐步拆解其中的技术细节。

PHP验证码怎么生成?用GD库绘制随机字符和干扰线的实用技巧

一、基础环境准备

GD库是PHP处理图像的扩展,多数Linux发行版通过php-gd包提供。在写代码前,先用php -m | grep gd确认已加载。若未启用,需修改php.ini取消extension=gd前的注释并重启服务。

验证码通常依赖Session保存正确值,因此调用session_start()必须位于任何输出之前。很多新手把图片输出和HTML混排,导致header报错,这点后面会专门说明。

二、完整生成代码示例

以下代码演示了创建画布、写随机字符、画干扰线并输出PNG的整个过程。注意所有小于号、大于号在pre内部都已转义。

<?php
session_start();

// 1. 创建画布
$width = 120;
$height = 40;
$image = imagecreatetruecolor($width, $height);

// 2. 分配颜色
$bgColor = imagecolorallocate($image, 240, 240, 240);
imagefill($image, 0, 0, $bgColor);

// 3. 生成随机字符
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$length = 4;
$code = '';
for ($i = 0; $i < $length; $i++) {
    $char = $chars[rand(0, strlen($chars) - 1)];
    $code .= $char;
    $textColor = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120));
    $x = 15 + $i * 25;
    $y = rand(25, 35);
    imagestring($image, 5, $x, $y, $char, $textColor);
}
$_SESSION['captcha'] = $code;

// 4. 绘制干扰线
for ($i = 0; $i < 5; $i++) {
    $lineColor = imagecolorallocate($image, rand(100, 220), rand(100, 220), rand(100, 220));
    imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $lineColor);
}

// 5. 输出图像
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>

上述脚本直接访问时会返回一张图片。字符集去掉了易混的0、O、1、I,降低用户辨认难度。每个字符的纵坐标随机偏移,让机器切分字符更困难。

干扰线使用imageline()随机起止点,颜色与背景有一定反差但不刺眼。若线条过密会影响真人阅读,一般控制在3到6条之间。

三、使用TTF字体提升安全性

imagestring()仅用内置字体,容易被针对性识别。更优方案是imagettftext()加载TrueType字体,支持旋转与大小调整。

<?php
$font = '/var/www/fonts/arial.ttf';
for ($i = 0; $i < $length; $i++) {
    $angle = rand(-15, 15);
    $size = rand(18, 24);
    imagettftext($image, $size, $angle, 15 + $i * 28, 30, $textColor, $font, $code[$i]);
}
?>

字体文件需服务器可读,路径写绝对地址最稳妥。角度随机让字符轻微倾斜,OCR通用模型准确率明显下降,而人眼仍可在瞬间读完。

要注意imagettftext()的编码必须为UTF-8,若字符乱码多是文件或字符串编码不匹配,可用mb_convert_encoding()转换。

四、常见坑与排查

第一,Session跨页丢失:表单页和验证页若不在同一域名或路径,session_id可能不一致。建议统一入口或显式传递。

第二,图像破损:在header()前有任何echo或空白,PNG头会被污染。用ob_clean()清空缓冲再输出可应急,但根本办法是分离验证码脚本。

问题现象可能原因解决办法
页面显示乱码方块字体路径错误检查文件权限与绝对路径
验证码总不匹配Session未开启在脚本首行加session_start()
图片裂图输出了多余字符删除所有空白与echo

把验证值存入Session后,表单提交时比对$_POST['input']$_SESSION['captcha']即可。比对前统一转大写,避免用户大小写纠结。

五、小结与扩展

GD库方案零依赖、性能好,适合低中等安全场景。若需更强抗机器能力,可加干扰点、正弦曲线或融合前端点击行为验证。

生产环境建议给验证码接口限流,防止攻击者高频刷新消耗CPU。同时定期换字体与字符集,让已训练的识别脚本失效。

PHPGD库验证码修改时间:2026-08-06 19:18:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。