在php项目中,图形验证码是防止恶意表单提交、机器人刷接口的重要防护手段,核心实现依赖php的gd库扩展,通过生成随机字符、绘制图形、添加干扰元素等步骤完成。如果服务器未开启gd库,需要先到php.ini中开启extension=gd扩展,重启服务后即可使用。

php生成验证码的核心步骤
完整的php验证码生成流程可以分为四个核心环节,每个环节的作用如下:
- 生成随机验证码字符:通常选择数字、大小写字母组合,长度控制在4-6位,兼顾安全性和用户输入体验
- 创建画布与设置背景:使用gd库函数创建指定尺寸的画布,设置背景颜色,避免纯白背景容易被识别
- 绘制字符与干扰元素:将随机字符逐个绘制到画布上,同时添加干扰点、干扰线,提升验证码被机器识别的难度
- 存储验证码并输出图像:将生成的验证码字符存入session,方便后续验证,同时将画布输出为png格式图像
完整的php验证码生成代码
以下是可直接使用的php生成图形验证码的完整代码,包含上述所有核心步骤:
<?php
// 开启session,用于存储验证码字符
session_start();
// 1. 生成随机验证码字符,4位数字和字母组合
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$captcha_len = 4;
$captcha_code = '';
for ($i = 0; $i < $captcha_len; $i++) {
$captcha_code .= $characters[rand(0, strlen($characters) - 1)];
}
// 将验证码存入session
$_SESSION['captcha_code'] = $captcha_code;
// 2. 创建画布,设置宽高
$width = 120;
$height = 40;
$image = imagecreatetruecolor($width, $height);
// 3. 设置颜色
$bg_color = imagecolorallocate($image, 240, 240, 240); // 浅灰色背景
$text_color = imagecolorallocate($image, 0, 0, 0); // 黑色文字
$line_color = imagecolorallocate($image, 200, 200, 200); // 干扰线颜色
$point_color = imagecolorallocate($image, 180, 180, 180); // 干扰点颜色
// 填充背景
imagefilledrectangle($image, 0, 0, $width, $height, $bg_color);
// 4. 添加干扰线,5条随机曲线
for ($i = 0; $i < 5; $i++) {
imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $line_color);
}
// 5. 添加干扰点,100个随机像素点
for ($i = 0; $i < 100; $i++) {
imagesetpixel($image, rand(0, $width), rand(0, $height), $point_color);
}
// 6. 绘制验证码字符,每个字符随机位置、随机大小
$font_size = 5; // 内置字体大小,范围1-5
$char_width = $width / $captcha_len;
for ($i = 0; $i < $captcha_len; $i++) {
$x = $i * $char_width + rand(2, 8);
$y = rand(5, $height - 20);
imagestring($image, $font_size, $x, $y, $captcha_code[$i], $text_color);
}
// 7. 设置响应头为png图像,输出画布并销毁资源
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>
验证码的验证方法
生成验证码后,需要在表单提交时验证用户输入的验证码是否正确,验证流程如下:
<?php
session_start();
// 获取用户输入的验证码,转为小写统一比对
$user_input = strtolower(trim($_POST['captcha'] ?? ''));
$real_code = strtolower($_SESSION['captcha_code'] ?? '');
if ($user_input === $real_code && $real_code !== '') {
echo '验证码验证通过';
// 验证通过后清空session中的验证码,避免重复使用
unset($_SESSION['captcha_code']);
} else {
echo '验证码错误';
}
?>
常见问题与优化建议
在实际使用php生成验证码时,可能会遇到以下问题,可针对性优化:
- 如果验证码显示乱码,检查服务器是否支持gd库的字体函数,也可替换为自定义字体文件,使用
imagettftext函数绘制,文字样式更丰富 - 为提升安全性,可定期更新随机字符集,避免固定字符容易被穷举
- 验证码验证通过后要及时清空session中的存储值,防止同一验证码被多次提交使用
- 可添加验证码过期时间逻辑,比如生成时记录时间戳,超过5分钟未使用则自动失效