验证码实现

来源:互联网 发布:淘宝商家客服兼职 编辑:程序博客网 时间:2024/06/04 18:28

一、提前了解


1. GD库

在PHP中,通过使用GD扩展库提供的一系列API接口实现对图像的处理,包括创建新图像和处理已有图像(调整大小、缩略图、旋转添加水印等)。
我们可以到https://libgd.github.io/下载GD库。
通过GD库处理图像的操作,都是先在内存中处理,操作完以后再以文件流的方式输出到浏览器或保存到浏览器。

2.创建图像步骤

(1)创建画布:就是在内存中开辟一块临时区域,用于存储图图像信息;
(2)绘制图像:使用各种函数设置图像颜色,背景,填充画笔,绘制图形等;
(3)输出图形:以某种格式保存到服务器或者输出到浏览器显示给用户。
注意:直接输出之前一定要用header( )告诉浏览器以图像格式来处理该输出,比如header(‘Content-type: image/png’);
(4)释放资源:节约系统资源考虑,需及时清除。

二、实现


1. 原理

在一个矩形画布上面生成随机字母数字或汉字,每个字体设置随机的颜色和旋转角度(小于90度),画布加上背景色和一些干扰元素(点、线、弧)

2. 代码

<?php/** * 验证码类     * @author prkom */class Code{    //资源    private $img;    //画布宽度    public $width = 150;    //画布高度    public $height = 45;    //背景颜色    public $bgColor = "#ffffff";    //验证码    public $code;    //验证码的随机种子    public $codeStr = "123456789abcdefghijklmnpqrstuvwsyz";    //验证码长度    public $codeLen = 4;    //验证码字体    public $font = "";      //具体环境具体需要更改路径    //验证码字体大小    public $fontSize = 22;    //验证码字体颜色    public $fontColor = "";    /**     * 构造函数     */    public function __construct($arr = array()) {        $width = '';        $height = '';        $codeLen = '';        $fontSize = '';        $bgColor = '';        $fontColor = '';        if(!empty($arr)){           extract($arr);   //将数组参数拆分,变成变量去使用。        }         $this->font = BASEPATH . "fonts/font.ttf";               if (!is_file($this->font)) {            error("验证码字体文件不存在");        }        $this->width = empty($width) ? $this->width : $width;        $this->height = empty($height) ? $this->height : $height;        $this->bgColor = empty($bgColor) ? $this->bgColor : $bgColor;        $this->codeLen = empty($codeLen) ? $this->codeLen : $codeLen;        $this->fontSize = empty($fontSize) ? $this->fontSize : $fontSize;        $this->fontColor = empty($fontColor) ? $this->fontColor : $fontColor;        $this->create();//生成验证码    }    /**     * 返回验证码     */    public function getCode() {        return $this->code;    }    /**     * 建画布     */    public function create() {        if (!$this->checkGD())            return false;        $w = $this->width;        $h = $this->height;        $bgColor = $this->bgColor;        $img = imagecreatetruecolor($w, $h);    //创建画布        /**         * 设置背景颜色         * @param  $img [资源]         * @param  R         * @param  G         * @param  B         * hexdec是将16进制转换成10进制         */        $bgColor = imagecolorallocate($img, hexdec(substr($bgColor, 1, 2)), hexdec(substr($bgColor, 3, 2)), hexdec(substr($bgColor, 5, 2)));        imagefill($img, 0, 0, $bgColor);    //填充背景        $this->img = $img;        $this->createLine();        $this->createFont();        $this->createPix();        $this->createRec();    }    /**    *  画线    */    private function createLine(){        $w = $this->width;        $h = $this->height;        $line_color = "#D0D0D0";        $color = imagecolorallocate($this->img, hexdec(substr($line_color, 1, 2)), hexdec(substr($line_color, 3, 2)), hexdec(substr($line_color, 5, 2)));        $line_height = $h/10;        for($i=0;$i<10;$i++){//直线            $step = $line_height*$i+2;            imageline($this->img, 0, $step, $w, $step, $color);        }        $line_width = $w/10;        for($i=0;$i<10;$i++){//斜线            $step =$line_width*$i+2;            imageline($this->img, $step-2, 0, $step+2,$h, $color);        }    }    /**     * 写入验证码文字     */    private function createFont() {        $this->createCode();    //引入随机生成的验证码        $color = $this->fontColor;        if (!empty($color)) {            $fontColor = imagecolorallocate($this->img, hexdec(substr($color, 1, 2)), hexdec(substr($color, 3, 2)), hexdec(substr($color, 5, 2)));        }        $x = ($this->width - 10) / $this->codeLen;        for ($i = 0; $i < $this->codeLen; $i++) {            if (empty($color)) {                $fontColor = imagecolorallocate($this->img, mt_rand(50, 155), mt_rand(50, 155), mt_rand(50, 155));            }            imagettftext($this->img, $this->fontSize, mt_rand(- 30, 30), $x * $i + mt_rand(6, 10), mt_rand($this->height / 1.3, $this->height - 5), $fontColor, $this->font, $this->code [$i]);        }        $this->fontColor = $fontColor;    }    /**     * 干扰元素     */    private function createPix() {        $pix_color = $this->fontColor;        //画点        for ($i = 0; $i < 50; $i++) {            imagesetpixel($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), $pix_color);        }        //画线        for ($i = 0; $i < 2; $i++) {            imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $pix_color);        }        //画圆弧        for ($i = 0; $i < 1; $i++) {            // 设置画线宽度           // imagesetthickness($this->img, mt_rand(1, 3));            imagearc($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height)                    , mt_rand(0, 160), mt_rand(0, 200), $pix_color);        }        imagesetthickness($this->img, 1);   //设置画线的宽度    }    /**     * 画矩形边框     */    private function createRec() {        imagerectangle($this->img, 0, 0, $this->width - 1, $this->height - 1, $this->fontColor);    }    /**     * 验证GD库是否打开imagepng函数是否可用     */    private function checkGD() {            return extension_loaded('gd') && function_exists("imagepng"); //使用了两个系统函数分别检测扩展和函数    }     /**     * 生成随机验证码     */    private function createCode() {        $code = '';        for ($i = 0; $i < $this->codeLen; $i++) {            $code .= $this->codeStr [mt_rand(0, strlen($this->codeStr) - 1)];        }        $this->code = strtoupper($code);        if(!isset($_SESSION)){  //确保开启了session            session_start();        }        $_SESSION ['code'] = $this->code;    }    /**     * 显示验证码     */    public function show() {        header("Content-type:image/png");        imagepng($this->img);        imagedestroy($this->img);        exit;    }}
1 0