PHP GD库实现验证码生成:从基础到完整流程

听雨眠
听雨眠
发布时间:2026-10-14| 2人浏览过
原创

在Web开发中,验证码是防止机器自动化注册和暴力破解的有效手段。本文将基于PHP的GD库,逐步演示如何从零开始编写一个包含随机背景、干扰元素及随机文本的验证码生成脚本,解析核心函数用法,并提供可直接运行的代码示例。

结果与准备

最终目标是生成一张宽高为 150x50 像素的 JPEG 格式图片,内容包含4位随机字母或数字,并辅以随机颜色的线条和噪点以增强识别难度。操作环境需支持 PHP 且开启 gd 扩展。

第1步:初始化画布与背景

首先建立图像资源并设置HTTP头,确保浏览器将其识别为图片而非HTML文本。

  • 入口:新建 .php 文件(如 captcha.php)。
  • 动作:
  1. 使用 imagecreatetruecolor($width, $height) 创建真彩色画布。
  2. 调用 imagecolorallocate() 获取颜色资源,配合 mt_rand(0, 255) 生成红绿蓝随机值。
  3. 使用 imagefill() 将背景填充至整个画布。

该步骤决定了验证码的基础外观。若未显式指定颜色,默认为黑色背景。

<?php
header("Content-Type:text/html;Charset=UTF-8"); // 声明编码
header("Content-Type:image/jpeg");              // 通知浏览器这是JPEG图片

$img = imagecreatetruecolor(150, 50);           // 创建 150x50 画布
$bgcolor = imagecolorallocate($img, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imagefill($img, 0, 0, $bgcolor);               // 填充背景
?>

生成的纯随机色彩背景效果图:

第2步:添加干扰元素

为了防止简单的OCR软件秒破验证码,需要加入视觉干扰。主要手段包括绘制随机线段和散布随机像素点。

  • 绘制干扰线:使用循环多次调用 imageline(),起点和终点坐标均设置为画布范围内的随机值。
  • 绘制干扰点:使用循环多次调用 imagesetpixel(),在指定坐标上绘制单个像素点。

注意:imageline 接收两个点的坐标,而 imagesetpixel 仅接收一个点的坐标。坐标原点位于左上角 (0,0)。

// 添加3条随机干扰线
for($i=0; $i<3; $i++) {
    $linecolor = imagecolorallocate($img, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
    imageline($img, mt_rand(0,150), mt_rand(0,50), mt_rand(0,150), mt_rand(0,50), $linecolor);
}

// 添加25个随机干扰点
for($i=0; $i<25; $i++) {
    $dotcolor = imagecolorallocate($img, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
    imagesetpixel($img, mt_rand(0,150), mt_rand(0,50), $dotcolor);
}

加入干扰线与噪点后的效果图:

第3步:写入随机字符

这是验证码的核心部分。我们使用 TrueType 字体函数 imagettftext() 来绘制文字,以保证更好的显示效果和中文字体支持潜力。

  • 字符集定义:选取一组不易混淆的字母和数字(如去除 'O', 'I', 'l' 等)。
  • 坐标计算:将宽度平均分为4份,确定每个字符的起始X轴位置。
  • 角度旋转:通过 mt_rand(-15, 15) 随机调整文字倾斜角度,增加识别难度。
  • 字体路径:imagettftext 需要绝对路径指向 .ttf 字体文件。示例中使用的是 Windows 系统的 Verdana 字体路径,Linux 用户需修改为系统可用字体路径(如 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf)。
$rand_str = "qwertyuiopasdfghjklzxcvbnm1234567890";
$str_arr = array();

// 随机抽取4个字符
for($i = 0; $i < 4; $i++) {
    $pos = mt_rand(0, strlen($rand_str)-1);
    $str_arr[] = $rand_str[$pos];
}

$x_start = 150 / 4;

foreach ($str_arr as $key) {
    $fontcolor = imagecolorallocate($img, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
    // 参数顺序:图像, 字号, 角度, X坐标, Y坐标, 颜色, 字体文件, 文本
    imagettftext($img, 25, mt_rand(-15,15), $x_start, 35, $fontcolor, "C:/Windows/Fonts/Verdana.TTF", $key);
    $x_start += 20;
}

最终生成的完整验证码示例:

完成判断与后续处理

当所有绘图操作完成后,按以下步骤结束请求:

  1. 输出图像:调用 imagejpeg($img) 将内存中的图像数据发送出去。
  2. 释放资源:调用 imagedestroy($img) 销毁画布,释放服务器内存。
imagejpeg($img);
imagedestroy($img);

简要总结

上述就是PHP生成验证码的详细内容,更多关于PHP验证码实现与GD库使用的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。