PHP 实现简单图片验证码
验证码是网站会员系统中不可缺少的,目前验证码有很多种,但用的比较多的还是图片验证码,这里就用面向对象的方式来简单实现图片验证码,
注意!我这里使用的是 PHP 的 gd 库,如果要查看是否启用了 gd 库可以建立一个 phpinfo.php 文件,在文件中加入一句 phpinfo()
,访问 phpinfo.php 就可以查看是否启用了 gd 库,如果 GD Support
为 enabled
就是已启用。
如果要在 Windows 启用 gd 库可以打开 PHP 的安装目录,用文本编辑器打开 php.ini
,去除 xtension=php_gd2.dll
前面的注释即可。
PHP类
PHP代码:
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017/10/6
* Time: 20:44
*/
class Verification {
protected $fontfile = ''; // 字体文件
protected $width = 120; // 图片宽度 默认120
protected $height = 40; // 图片高度 默认40
protected $size = 20; // 字体大小 默认20
protected $length = 4; // 长度 默认4个字
protected $image = null; // 画布资源
protected $snow = 0; // 雪花干扰 默认没有干扰
protected $pixel = 0; // 像素点干扰 默认没有干扰
protected $line = 0; // 线段干扰 默认没有干扰
// 初始化数据
public function __construct($config = array()) {
if (is_array($config) && count($config) > 0) {
// 检测字体文件是否存在
if (isset($config['fontfile']) && is_file($config['fontfile'])) {
$this->fontfile = $config['fontfile']; // 设置字体文件位置
}else {
return false;
}
// 判断是否传入了宽度和宽度是否大于0
if (isset($config['width']) && $config['width'] > 0) {
// 设置宽度属性为传入的宽度
$this->width = (int)$config['width'];
}
// 判断是否传入高度和高度是否大于0
if (isset($config['height']) && $config['height'] > 0) {
$this->height = (int)$config['height']; // 设置高度属性
}
// 判断是否传入了字体大小和是否大于0
if (isset($config['size']) && $config['size'] > 0) {
$this->size = (int)$config['size']; // 设置字体大小属性
}
// 判断是否传入了验证码长度和长度是否大于0
if (isset($config['length']) && $config['length'] > 0) {
$this->length = (int)$config['length']; // 设置长度
}
// 判断是否设置了雪花干扰以及雪花数量是否大于0
if (isset($config['snow']) && $config['lsnow'] > 0) {
$this->snow = (int)$config['snow']; // 设置雪花干扰
}
// 判断是否设置了像素点干扰和数量是否大于0
if (isset($config['pixel']) && $config['pixel'] > 0) {
$this->pixel = (int)$config['pixel']; // 设置像素点干扰
}
// 判断是否设置了线条干扰和线条数量
if (isset($config['line']) && $config['line'] > 0) {
$this->line = (int)$config['line'];
}
$this->image = imagecreatetruecolor($this->width,$this->height); // 创建画布
return $this->image; // 返回i画布资源
}else {
return false;
}
}
// 生成验证码
public function getCaptcha() {
// 创建白色作为背景
$white = imagecolorallocate($this->image,255, 255, 255);
// 填充背景颜色
imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $white);
// 调用生成验证码内容的方法
$str = $this->generateStr($this->length);
// 判断生成内容是否成功
if (false === $str) {
return false;
}
$fontfile = $this->fontfile; // 设置字体文件位置
// 使用for循环来生成图片验证码,循环次数是验证码的长度
for ($i = 0;$i < $this->length;$i ++) {
$size = $this->size; // 设置字体大小
$angle = rand(-30, 30); // 设置字体角度
$x = ceil($this->width / $this->length) * $i + rand(5, 10); // 设置X轴位置
$y = ceil($this->height / 1.5); // 设置X轴位置
// 设置字体颜色,调用生成随机颜色的方法
$color = $this->getRandColor();
$text = $str{$i}; // 设置验证码内容
// 把验证码添加到画布上
imagettftext($this->image, $size, $angle, $x, $y, $color, $fontfile, $text);
}
// 是否需要雪花干扰
if ($this->snow > 0) {
$this->getSnow();
}else {
// 只有在没有雪花干扰的情况下才可以使用像素点和线段干扰
if ($this->pixel) {
$this->getPixel();
}
if ($this->line) {
$this->getLine();
}
}
header('content-type:image/png'); // 设置显示方式
imagepng($this->image); // 把生成的验证码图片显示在网页上
imagedestroy($this->image); // 销毁画布 节省资源
return strtolower($str); // 返回生成的验证码内容,用来设置session验证
}
// 生成雪花干扰
protected function getSnow() {
for ($i = 0;$i < $this->snow;$i ++) {
imagestring($this->image, rand(1, 5), rand(0, $this->width), rand(0, $this->height), '*', $this->getRandColor());
}
}
// 生成像素点干扰
protected function getPixel() {
for ($i = 0;$i < $this->pixel;$i ++) {
imagesetpixel($this->image, rand(0, $this->width), rand(0, $this->height), $this->getRandColor());
}
}
// 线段干扰
protected function getLine() {
for ($i = 0;$i < $this->line;$i ++) {
imageline($this->image, rand(0, $this->width), rand(0, $this->height), rand(0, $this->width), rand(0, $this->height), $this->getRandColor());
}
}
// 生成验证码字符
protected function generateStr($length = 4) {
// 判断验证码长度是否小于1或大于30
if ($length < 1 || $length > 30) {
return false;
}else {
// 验证码可能出现的内容
$chars = array(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S','T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9'
);
}
// 取出指定长度的验证码
$str = join('', array_rand(array_flip($chars), $length));
return $str;
}
// 用来生成随机颜色的
protected function getRandColor() {
return imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
}
}
使用方法
对象接收一个数组,除字体文件以外其他参数可以省略,省略的参数会使用默认参数,下面是简单说明:
参数 | 类型 | 参数可省略 | 说明 |
---|---|---|---|
fontfile | string | 否 | 字体文件名称 |
width | int | 是 | 图片宽度,默认120px |
height | int | 是 | 图片高度,默认40px |
size | int | 是 | 字体大小,默认20px |
length | int | 是 | 验证码长度,默认4个字 |
snow | int | 是 | 雪花干扰,默认为0,没有干扰 |
pixel | int | 是 | 像素点干扰,默认为0,没有干扰 |
line | int | 是 | 线条干扰,默认为0,没有干扰 |
代码:
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017/10/8
* Time: 16:55
*/
require_once 'verification_class.php'; // 引入类文件
$arr = array(
'fontfile'=>'fonts/arial.ttf', // 字体文件位置
'line'=>4, // 设置线条干扰数量为4
'pixel'=>50 // 设置像素点干扰为50
);
$img = new Verification($arr); // 实例化对象并且传入数组
session_start(); // 启用session
$_SESSION['str'] = $img->getCaptcha(); // 把返回的验证码保存到session
完整地传入数组参数可在类属性看到
最终效果如下:
验证码的每一个字都是随机颜色,角度也是随机的,如果要让验证码在 img
标签显示 就把 img
的 src
设置为调用类的 php 文件即可。
验证方法
直接判断表单提交的参数和 session
保存的验证码是否一致即可。
这就是简单实现图片验证码的方法,这个验证码还有很大的优化空间。
代码下载可点击下方的下载代码链接,百度网盘提取码:w39g
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/9/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。