VerificationCode 类封装了验证码图片生成全流程:随机码生成、背景绘制、干扰线/点绘制、文字渲染、图片输出。支持 TTF 字体(imagettftext)与内置字体(imagestring)双模式。
<?php
class VerificationCode {
private $charset = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'; // 去除易混淆字符
private $code = '';
private $codelen = 4;
private $width = 110;
private $height = 30;
private $img;
private $font = 'CALIBRIZ.TTF'; // 相对路径或绝对路径 C:/Windows/Fonts/CALIBRIZ.TTF
private $fontSize = 25;
private $fontColor;
public function __construct() {
// 可在此注入配置:$this->font = '/path/to/font.ttf';
}
// 生成随机验证码字符串
private function createCode() {
$len = strlen($this->charset) - 1;
for ($i = 0; $i < $this->codelen; $i++) {
$this->code .= $this->charset[mt_rand(0, $len)];
}
}
// 创建画布并填充随机浅色背景
private function createBg() {
$this->img = imagecreatetruecolor($this->width, $this->height);
$bgColor = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
imagefilledrectangle($this->img, 0, 0, $this->width, $this->height, $bgColor);
}
// 绘制验证码文字
private function createFont() {
$x = $this->width / $this->codelen;
for ($i = 0; $i < $this->codelen; $i++) {
$this->fontColor = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
// TTF 字体模式:支持旋转、抗锯齿
imagettftext($this->img, $this->fontSize, mt_rand(-30, 30), $i * $x + mt_rand(1, 5), $this->height / 1.4, $this->fontColor, $this->font, $this->code[$i]);
// 内置字体备选:imagestring($this->img, 5, $i * $x + mt_rand(1, 5), 5, $this->code[$i], $this->fontColor);
}
}
// 绘制干扰线与噪点
private function createDisturb() {
// 干扰线
for ($i = 0; $i < 6; $i++) {
$color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
}
// 噪点(雪花)
for ($i = 0; $i < 100; $i++) {
$color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
}
}
// 输出 PNG 并销毁资源
private function outPut() {
header('Content-Type: image/png');
imagepng($this->img);
imagedestroy($this->img);
}
// 公开接口:生成并输出验证码图片
public function showCode() {
$this->createBg();
$this->createCode();
$this->createDisturb();
$this->createFont();
$this->outPut();
}
// 获取生成的验证码(小写,便于不区分大小写验证)
public function getCode() {
return strtolower($this->code);
}
}
?>
code.php(生成验证码图片并存入 Session):
<?php
session_start();
require_once 'VerificationCode.class.php';
$code = new VerificationCode();
// 可自定义配置:$code->codelen = 5; $code->width = 130;
$_SESSION['captcha'] = $code->getCode(); // 存入 Session 供后续验证
$code->showCode();
?>
前端表单:
<input type="text" name="captcha" placeholder="输入验证码" />
<img src="code.php" alt="点击刷新" style="cursor:pointer; vertical-align:middle;" onclick="this.src='code.php?t='+Math.random()" />
后端验证:
<?php
session_start();
if (strtolower($_POST['captcha']) === $_SESSION['captcha']) {
echo "验证通过";
} else {
echo "验证码错误";
}
?>
| 方面 | 说明 |
|---|---|
| 字体文件 | 确保 CALIBRIZ.TTF 可读,建议放在项目目录下并用绝对路径;Windows 系统字体通常在 C:/Windows/Fonts/。 |
| GD 扩展 | 需开启 extension=gd,且支持 FreeType(imagettftext 需要)。 |
| 随机性 | 使用 mt_rand 足够;高安全场景可改用 random_int (PHP 7+)。 |
| Session 安全 | 验证后建议 unset($_SESSION['captcha']) 防止重复使用。 |
| 可访问性 | 提供语音验证码或刷新按钮,照顾视障用户。 |
| 性能 | 高并发下可考虑缓存生成的图片或使用更轻量的库(如 gregwar/captcha)。 |
将 $charset 改为常用汉字数组,createCode 随机选取 4 个汉字,字体需支持中文(如 msyh.ttc 微软雅黑)。