菜鸟科技网

PHP验证码编写步骤有哪些?

PHP编写验证码的过程主要涉及图像生成、随机字符生成、干扰元素添加以及与前端表单的交互验证,下面将详细介绍实现步骤,包括基础验证码、GD库操作、Session存储验证码值以及前端表单提交验证等关键环节。

PHP验证码编写步骤有哪些?-图1
(图片来源网络,侵删)

验证码的基本原理

验证码的主要目的是区分用户是计算机还是人,防止恶意程序自动提交表单,其核心流程包括:服务器生成随机字符串并绘制成图像,将字符串存储在Session中,用户提交表单时将输入值与Session中的值进行比对,验证通过则允许操作,否则提示错误。

环境准备

PHP生成验证码主要依赖GD库,确保服务器已安装并启用GD库,通过phpinfo()函数检查GD Support是否为enabled,若未启用,可在php.ini中取消;extension=gd前的分号并重启服务。

生成随机验证码字符串

验证码通常由数字、字母或组合而成,长度一般为4-6位,使用以下代码生成随机字符串:

function generateRandomCode($length = 4) {
    $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $chars[rand(0, strlen($chars) - 1)];
    }
    return $code;
}
$code = generateRandomCode(4);

使用GD库绘制验证码图像

创建画布

$imageWidth = 120;
$imageHeight = 40;
$image = imagecreatetruecolor($imageWidth, $imageHeight);

定义颜色

$backgroundColor = imagecolorallocate($image, 255, 255, 255); // 白色背景
$textColor = imagecolorallocate($image, 0, 0, 0); // 黑色文字
$noiseColor = imagecolorallocate($image, 150, 150, 150); // 干扰元素颜色

填充背景

imagefill($image, 0, 0, $backgroundColor);

添加干扰线

for ($i = 0; $i < 5; $i++) {
    imageline($image, rand(0, $imageWidth), rand(0, $imageHeight), 
             rand(0, $imageWidth), rand(0, $imageHeight), $noiseColor);
}

添加干扰点

for ($i = 0; $i < 50; $i++) {
    imagesetpixel($image, rand(0, $imageWidth), rand(0, $imageHeight), $noiseColor);
}

输出验证码文字

$fontFile = 'arial.ttf'; // 确保服务器有该字体文件,或使用默认字体
$fontSize = 20;
$x = 20;
$y = 30;
for ($i = 0; $i < strlen($code); $i++) {
    $angle = rand(-10, 10); // 随机倾斜角度
    imagettftext($image, $fontSize, $angle, $x, $y, $textColor, $fontFile, $code[$i]);
    $x += 25; // 调整字符间距
}

输出图像并释放资源

header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);

Session存储验证码值

在生成图像前,将验证码字符串存入Session:

PHP验证码编写步骤有哪些?-图2
(图片来源网络,侵删)
session_start();
$_SESSION['captcha_code'] = $code;

完整验证码生成示例代码

<?php
session_start();
function generateCaptcha($length = 4) {
    $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $code = '';
    for ($i = 0; $i < $length; $i++) {
        $code .= $chars[rand(0, strlen($chars) - 1)];
    }
    return $code;
}
$imageWidth = 120;
$imageHeight = 40;
$image = imagecreatetruecolor($imageWidth, $imageHeight);
$backgroundColor = imagecolorallocate($image, 255, 255, 255);
$textColor = imagecolorallocate($image, 0, 0, 0);
$noiseColor = imagecolorallocate($image, 150, 150, 150);
imagefill($image, 0, 0, $backgroundColor);
for ($i = 0; $i < 5; $i++) {
    imageline($image, rand(0, $imageWidth), rand(0, $imageHeight), 
             rand(0, $imageWidth), rand(0, $imageHeight), $noiseColor);
}
for ($i = 0; $i < 50; $i++) {
    imagesetpixel($image, rand(0, $imageWidth), rand(0, $imageHeight), $noiseColor);
}
$code = generateCaptcha(4);
$_SESSION['captcha_code'] = $code;
$fontFile = 'arial.ttf';
$fontSize = 20;
$x = 20;
$y = 30;
for ($i = 0; $i < strlen($code); $i++) {
    $angle = rand(-10, 10);
    imagettftext($image, $fontSize, $angle, $x, $y, $textColor, $fontFile, $code[$i]);
    $x += 25;
}
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>

前端表单与后端验证

前端表单(HTML)

<form action="verify.php" method="post">
    <img src="captcha.php" onclick="this.src='captcha.php?'+Math.random()" alt="验证码">
    <input type="text" name="captcha_input" placeholder="请输入验证码">
    <button type="submit">提交</button>
</form>

点击图片刷新验证码通过Math.random()实现URL参数变化,避免浏览器缓存。

后端验证(PHP)

<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $userInput = $_POST['captcha_input'];
    if (isset($_SESSION['captcha_code']) && strtolower($userInput) == strtolower($_SESSION['captcha_code'])) {
        echo "验证成功!";
    } else {
        echo "验证码错误!";
    }
    unset($_SESSION['captcha_code']); // 验证后清除Session
}
?>

验证码增强技巧

  1. 字符变形:通过imagettftext()angle参数使字符倾斜,增加机器识别难度。
  2. 背景干扰:添加随机曲线、噪点或复杂背景图案。
  3. 字体选择:使用手写风格或艺术字体,避免标准字体。
  4. 时间限制:设置Session有效期,如30秒后验证码失效。

常见问题与解决方案

问题现象 可能原因 解决方法
验证码图像无法显示 GD库未启用或路径错误 检查php.ini中GD扩展,确认字体文件路径
验证码始终提示错误 Session未开启或大小写敏感 确保调用session_start(),使用strtolower()统一大小写

相关问答FAQs

Q1:为什么验证码不区分大小写,但有时仍会验证失败?
A1:可能是Session未正确传递或浏览器缓存问题,建议在生成验证码时统一转换为小写存储(如$_SESSION['captcha_code'] = strtolower($code)),验证时也统一转换大小写比对,并确保表单提交时Session有效。

Q2:如何实现点击刷新验证码功能?
A2:在前端JavaScript中为验证码图片绑定点击事件,动态修改src属性添加随机参数(如Math.random())以绕过浏览器缓存,示例代码:

document.getElementById('captcha-img').onclick = function() {
    this.src = 'captcha.php?' + Math.random();
};
分享:
扫描分享到社交APP
上一篇
下一篇