PHP图形验证码需通过GD库生成随机字符并绘图,存入Session校验,支持第三方库或Base64内联方案。

如果您在PHP项目中需要实现用户登录或注册时的图形验证码功能,则需通过生成随机字符、绘制图像并验证用户输入来完成。以下是实现图形验证码制作与验证的具体步骤:
一、使用GD库生成图形验证码
GD库是PHP内置的图像处理扩展,可用于动态创建PNG或JPEG格式的验证码图片,核心在于生成随机字符串并将其绘制到画布上。
1、启用GD扩展:确认php.ini中已取消extension=gd的注释,并重启Web服务器。
2、创建验证码生成脚本(如verify_code.php):初始化画布尺寸,分配背景色与文字色。
立即学习“PHP免费学习笔记(深入)”;
3、生成4位随机字符串(含数字与大写字母):使用mt_rand()配合字符串索引抽取字符,避免易混淆字符如0/O/I/l。
4、在画布上逐个绘制字符,加入轻微旋转和位置偏移以增强防识别能力。
5、添加干扰点和干扰线:调用imagesetpixel()和imageline()随机绘制噪点。
6、输出图片头信息header('Content-Type: image/png'),并用imagepng()输出图像流。
二、将验证码存入Session供验证比对
生成验证码的同时必须将其明文值安全保存在服务端Session中,确保客户端无法直接获取,防止绕过验证。
1、在生成验证码图像前,启动Session:session_start()。
2、将生成的随机字符串赋值给$_SESSION['captcha_code']。
3、设置Session有效期:通过ini_set('session.gc_maxlifetime', 300)限定为5分钟。
4、确保Session未被覆盖或清空:在验证码脚本末尾不调用session_write_close()或session_destroy()。
5、验证码Session键名必须唯一且不可预测,禁止使用固定字符串如'code'作为通用键。
三、在表单页面嵌入验证码图片并提交校验
前端需展示验证码图片并提供输入框,提交时将用户输入与Session中存储的值进行严格比对,区分大小写且不允许多余空格。
1、在登录/注册HTML页面中插入<img src="verify_code.php?r=<?php echo time(); ?>" alt="验证码">,添加时间戳防止浏览器缓存。
2、为图片绑定点击事件,实现点击刷新:onclick="this.src='verify_code.php?r='+Math.random();"。
3、表单提交至验证处理器(如login_check.php),接收用户输入的验证码字段(如$_POST['captcha'])。
4、读取$_SESSION['captcha_code'],使用trim()清理两端空格后,用===进行全等判断。
5、验证通过后立即unset($_SESSION['captcha_code']),防止同一验证码被重复使用。
四、使用第三方类库(如Gregwar/Captcha)快速集成
Gregwar/Captcha是一个轻量级、无依赖的PHP验证码类库,支持字体自定义、中文、数学运算等模式,可跳过底层GD编码细节。
1、通过Composer安装:composer require gregwar/captcha。
2、在生成页面引入自动加载器并实例化:$captcha = new CaptchaBuilder();。
3、设置字符集与长度:$captcha->setCharacters('ABCDEFGHJKLMNPQRSTUVWXYZ23456789');。
4、构建并输出:$captcha->build(); $_SESSION['phrase'] = $captcha->getPhrase(); $captcha->output();。
5、注意该库默认不开启Session自动管理,仍需手动存取$_SESSION中的短语值。
五、基于Base64内联的无文件验证码方案
避免单独请求verify_code.php,将验证码图像直接编码为Data URI嵌入HTML,减少HTTP请求数,适用于静态化或CDN部署场景。
1、在生成脚本中不输出header,改用ob_start()捕获图像二进制数据。
2、调用imagepng($image, null)将图像写入输出缓冲区。
3、获取缓冲内容:$pngData = ob_get_contents(); ob_end_clean();。
4、编码为Base64:$base64 = 'data:image/png;base64,' . base64_encode($pngData);。
5、每次生成必须重新生成Session值并重置图像,禁止复用同一Base64字符串多次显示。











