PHP验证码类实现示例与集成方法
本文介绍如何利用 PHP 原生 GD 库封装高可配置的验证码类,解决传统 Web 应用登录接口容易遭受机器自动提交的问题。通过调整字符集混淆度、随机倾斜角度以及添加背景干扰线条与噪点,提升验证码的安全等级。文章包含完整的类定义代码、Session 状态管理逻辑以及前端异步刷新实现细节。
验证环境准备
在开始之前,请确认你的 PHP 环境已开启 gd 扩展。该方案依赖 GD 库的核心函数(如 imagecreatetruecolor、imagettftext)来绘制图像和渲染文字。如果你打算使用特定字体以增强视觉效果,需确保服务器系统存在对应的 .ttf 字体文件。
实现步骤详解
第1步:封装验证码类 VerificationCode
目的:构建独立的可复用组件,将验证码生成的核心逻辑隔离,便于后续修改参数(如宽度、高度、颜色或干扰程度)。
动作:新建文件 VerificationCode.class.php,定义类属性与私有绘图方法。
<?php
class VerificationCode{
private $charset="abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789"; // 移除易混淆字符如 i, l, 1, o, 0
private $code;
private $codelen=4; // 验证码长度
private $width=110; // 画布宽度
private $height=30; // 画布高度
private $img;
private $font="CALIBRIZ.TTF"; // 字体文件名,建议放置于同目录或指定绝对路径
private $fontSize=25;
private $fontColor;
public function __construct(){}
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);
// 浅灰色背景,减少对比度防止被简单分割
$color = imagecolorallocate($this->img,mt_rand(157,255),mt_rand(157,255),mt_rand(157,255));
imagefilledrectangle($this->img,0,0,$this->width,$this->height,$color);
}
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]);
// 如果不想用TTF,可以使用imagestring,但效果较粗糙
// 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->width),mt_rand(0,$this->width),mt_rand(0,$this->width),$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);
}
}
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);
}
}
?
第2步:编写服务端处理脚本 code.php
目的:处理 HTTP 请求,实例化验证码类,并将正确的验证码字符串存入 Session,以便后续接口校验。
操作:创建 code.php 作为验证码图片的源地址。
<?php
session_start();
require_once 'VerificationCode.class.php';
$code=new VerificationCode();
// 获取并统一转小写后存入 Session
$_SESSION['code']=$code->getCode();
// 输出图片到浏览器
$code->showCode();
?
第3步:前端页面集成展示
目的:在 HTML 表单中展示验证码,并确保用户点击或刷新时能够获取新的验证码实例。
操作:在登录/注册页面对应的 HTML 结构中加入以下片段。
验证码:<input type="text" name="code" /><img src="code.php" onclick="javascript:this.src='code.php?time='+Math.random();" />
这里利用 JavaScript 替换图片的 URL 查询参数,触发浏览器重新向 code.php 发起请求,从而在服务端生成全新的验证码图片。
注意事项
在实际业务场景中,如果不需要复杂的字体渲染,可以将 imagettftext 替换为 imagestring,这样无需依赖外部字体文件。但对于中文验证码,则必须使用支持 UTF-8 编码且包含对应字形的 TTF 字体配合 imagettftext 来实现。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









