PHP图片验证码如何实现?更加完善的封装
时间:2023年10月04日
/来源:网络
/编辑:佚名
以下是一个更完善的验证码类:
/**
* 验证码生成工具类
*/
class Captcha
{
protected $length = 4; // 验证码长度
protected $fonts = ['arial.ttf']; // 验证码字体
protected $width = 100; // 验证码宽度
protected $height = 40; // 验证码高度
protected $bg_color = [255, 255, 255]; // 背景颜色
protected $text_color = [0, 0, 0]; // 验证码字体颜色
protected $pixel_noise = 0; // 像素噪点密度
protected $line_noise = 0; // 直线噪点密度
public function __construct($options = [])
{
foreach ($options as $key => $value) {
$this->$key = $value;
}
}
public function generate()
{
// 创建画布
$image = imagecreatetruecolor($this->width, $this->height);
// 设定背景色
$bg_color = imagecolorallocate($image, ...$this->bg_color);
imagefill($image, 0, 0, $bg_color);
// 生成验证码字符串
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$str = '';
for ($i = 0; $i < $this->length; $i++) {
$str .= $chars[mt_rand(0, strlen($chars) - 1)];
}
// 绘制验证码字符串
$text_color = imagecolorallocate($image, ...$this->text_color);
$char_width = $this->width / $this->length;
$char_height = $this->height - 8;
$font_size = $char_height * 0.75;
foreach (str_split($str) as $i => $char) {
$font_file = __DIR__ . '/fonts/' . $this->fonts[mt_rand(0, count($this->fonts) - 1)];
$angle = mt_rand(-10, 10);
$x = $char_width * $i + ($char_width - $font_size) / 2;
$y = $char_height + $font_size / 2 - 4;
imagettftext($image, $font_size, $angle, $x, $y, $text_color, $font_file, $char);
}
// 添加像素噪点
if ($this->pixel_noise > 0) {
for ($i = 0; $i < $this->pixel_noise; $i++) {
$x = mt_rand(0, $this->width);
$y = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagesetpixel($image, $x, $y, $color);
}
}
// 添加直线噪点
if ($this->line_noise > 0) {
for ($i = 0; $i < $this->line_noise; $i++) {
$x1 = mt_rand(0, $this->width);
$y1 = mt_rand(0, $this->height);
$x2 = mt_rand(0, $this->width);
$y2 = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imageline($image, $x1, $y1, $x2, $y2, $color);
}
}
// 输出图像
header('Content-type: image/png');
imagepng($image);
// 释放资源
imagedestroy($image);
// 把验证码字符串存储到会话中
session_start();
$_SESSION['captcha'] = strtolower($str);
}
public function validate($input)
{
session_start();
$captcha = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : '';
unset($_SESSION['captcha']);
return strtolower($input) === strtolower($captcha);
}
}
示例使用方法:
// 实例化验证码生成器
$captcha = new Captcha([
'length' => 4, // 验证码长度
'width' => 120, // 验证码宽度
'height' => 32, // 验证码高度
'bg_color' => [240, 240, 240], // 背景颜色
'text_color' => [20, 20, 20], // 字体颜色
'pixel_noise' => 50, // 像素噪点密度
'line_noise' => 5, // 直线噪点密度
]);
// 生成验证码
$captcha->generate();
// 验证验证码
if ($captcha->validate($_POST['captcha'])) {
echo '验证通过';
} else {
echo '验证失败';
}
此验证码类有以下改进:
可以通过构造函数传递参数,而不需要通过类属性手动配置;
可以配置多个字体文件,每次绘制验证码时随机选择一个字体;
可以配置像素噪点和直线噪点密度。
/**
* 验证码生成工具类
*/
class Captcha
{
protected $length = 4; // 验证码长度
protected $fonts = ['arial.ttf']; // 验证码字体
protected $width = 100; // 验证码宽度
protected $height = 40; // 验证码高度
protected $bg_color = [255, 255, 255]; // 背景颜色
protected $text_color = [0, 0, 0]; // 验证码字体颜色
protected $pixel_noise = 0; // 像素噪点密度
protected $line_noise = 0; // 直线噪点密度
public function __construct($options = [])
{
foreach ($options as $key => $value) {
$this->$key = $value;
}
}
public function generate()
{
// 创建画布
$image = imagecreatetruecolor($this->width, $this->height);
// 设定背景色
$bg_color = imagecolorallocate($image, ...$this->bg_color);
imagefill($image, 0, 0, $bg_color);
// 生成验证码字符串
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$str = '';
for ($i = 0; $i < $this->length; $i++) {
$str .= $chars[mt_rand(0, strlen($chars) - 1)];
}
// 绘制验证码字符串
$text_color = imagecolorallocate($image, ...$this->text_color);
$char_width = $this->width / $this->length;
$char_height = $this->height - 8;
$font_size = $char_height * 0.75;
foreach (str_split($str) as $i => $char) {
$font_file = __DIR__ . '/fonts/' . $this->fonts[mt_rand(0, count($this->fonts) - 1)];
$angle = mt_rand(-10, 10);
$x = $char_width * $i + ($char_width - $font_size) / 2;
$y = $char_height + $font_size / 2 - 4;
imagettftext($image, $font_size, $angle, $x, $y, $text_color, $font_file, $char);
}
// 添加像素噪点
if ($this->pixel_noise > 0) {
for ($i = 0; $i < $this->pixel_noise; $i++) {
$x = mt_rand(0, $this->width);
$y = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imagesetpixel($image, $x, $y, $color);
}
}
// 添加直线噪点
if ($this->line_noise > 0) {
for ($i = 0; $i < $this->line_noise; $i++) {
$x1 = mt_rand(0, $this->width);
$y1 = mt_rand(0, $this->height);
$x2 = mt_rand(0, $this->width);
$y2 = mt_rand(0, $this->height);
$color = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
imageline($image, $x1, $y1, $x2, $y2, $color);
}
}
// 输出图像
header('Content-type: image/png');
imagepng($image);
// 释放资源
imagedestroy($image);
// 把验证码字符串存储到会话中
session_start();
$_SESSION['captcha'] = strtolower($str);
}
public function validate($input)
{
session_start();
$captcha = isset($_SESSION['captcha']) ? $_SESSION['captcha'] : '';
unset($_SESSION['captcha']);
return strtolower($input) === strtolower($captcha);
}
}
示例使用方法:
// 实例化验证码生成器
$captcha = new Captcha([
'length' => 4, // 验证码长度
'width' => 120, // 验证码宽度
'height' => 32, // 验证码高度
'bg_color' => [240, 240, 240], // 背景颜色
'text_color' => [20, 20, 20], // 字体颜色
'pixel_noise' => 50, // 像素噪点密度
'line_noise' => 5, // 直线噪点密度
]);
// 生成验证码
$captcha->generate();
// 验证验证码
if ($captcha->validate($_POST['captcha'])) {
echo '验证通过';
} else {
echo '验证失败';
}
此验证码类有以下改进:
可以通过构造函数传递参数,而不需要通过类属性手动配置;
可以配置多个字体文件,每次绘制验证码时随机选择一个字体;
可以配置像素噪点和直线噪点密度。
新闻资讯 更多
- 【建站知识】查询nginx日志状态码大于400的请求并打印整行04-03
- 【建站知识】Python中的logger和handler到底是个什么?04-03
- 【建站知识】python3拉勾网爬虫之(您操作太频繁,请稍后访问)04-03
- 【建站知识】xpath 获取meta里的keywords及description的方法04-03
- 【建站知识】python向上取整以50为界04-03
- 【建站知识】scrapy xpath遇见乱码解决04-03
- 【建站知识】scrapy爬取后中文乱码,解决word转为html 时cp1252编码问题04-03
- 【建站知识】scrapy采集—爬取中文乱码,gb2312转为utf-804-03