验证码是网站会员系统中不可缺少的,目前验证码有很多种,但用的比较多的还是图片验证码,这里就用面向对象的方式来简单实现图片验证码,

注意!我这里使用的是 PHP 的 gd 库,如果要查看是否启用了 gd 库可以建立一个 phpinfo.php 文件,在文件中加入一句 phpinfo() ,访问 phpinfo.php 就可以查看是否启用了 gd 库,如果 GD Supportenabled 就是已启用。

如果要在 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));
    }
}

使用方法

对象接收一个数组,除字体文件以外其他参数可以省略,省略的参数会使用默认参数,下面是简单说明:

参数类型参数可省略说明
fontfilestring字体文件名称
widthint图片宽度,默认120px
heightint图片高度,默认40px
sizeint字体大小,默认20px
lengthint验证码长度,默认4个字
snowint雪花干扰,默认为0,没有干扰
pixelint像素点干扰,默认为0,没有干扰
lineint线条干扰,默认为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 标签显示 就把 imgsrc 设置为调用类的 php 文件即可。

验证方法

直接判断表单提交的参数和 session 保存的验证码是否一致即可。

这就是简单实现图片验证码的方法,这个验证码还有很大的优化空间。

代码下载可点击下方的下载代码链接,百度网盘提取码:w39g

下载代码