• PHP-解析验证码类--学习笔记


    1.开始

    在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下。

    2.类图

     

    3.验证码类部分代码

    3.1  定义变量

        //随机因子
        private $charset = 'abcdefghjkmnprstuvwxyzABCDEFGJKMNPRSTUVWXYZ23456789';
        private $code;
        private $codeLen = 4;
    
        private $width = 130;
        private $heigh = 50;
        private $img;//图像
    
        private $font;//字体
        private $fontsize = 20;

    $charset 是随机因子,这里是去掉了几个不容易区分的字符,如字母"i,l,o,q",数字"0,1"。有必要可以加入一些中文或其他字符或算式等。

    $codeLen表示验证码长度,常见4位。

    3.2构造函数,设置验证码字体,生成一个真彩色图像img

    public function __construct()
        {
            $this->font = ROOT_PATH.'/font/Chowderhead.ttf';
            $this->img = imagecreatetruecolor($this->width, $this->heigh);
        }

     3.3从随机因子中随机抽取4个字符,作为$code验证码.

    //生成随机码
        private function createCode()
        {
            $_len = strlen($this->charset) - 1;
            for ($i = 0; $i < $this->codeLen; $i++) {
                $this->code .= $this->charset[mt_rand(0, $_len)];
            }
        }

    3.4生成验证码背景色.

    //生成背景
        private function createBg()
        {
    $color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
            imagefilledrectangle($this->img, 0, $this->heigh, $this->width, 0, $color);
    
        }

    其中mt_rand(157, 255),目的是随机取比较浅的颜色。

    3.5在图像上生成文字.

    //生成文字
        private function createFont()
        {
            $_x = $this->width / $this->codeLen;
            $_y = $this->heigh / 2;
            for ($i = 0; $i < $this->codeLen; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
                imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(3, 5), $_y + mt_rand(2, 4), $color, $this->font, $this->code[$i]);
            }
        }

    在图像上生成验证码文字,主要考虑文字在图像上的位置和每一个文字颜色。

    控制第n个文字的x轴位置 =  (图像宽度 / 验证码长度) * (n-1)  +  随机的偏移数;  其中n = {d1....n}

    控制第n个文字的y轴位置 =  图像高度 / 2 +  随机的偏移数;

    mt_rand(0, 156) 随机取文字颜色,0-156目的是取比较深的颜色。

    mt_rand(-30, 30) 随机的文字旋转。


    3.6在图像上生成线条和雪花

    //生成线条,雪花
        private function createLine()
        {
            for ($i = 0; $i < 15; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
                imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->heigh), mt_rand(0, $this->width), mt_rand(0, $this->heigh), $color);
            }
            for ($i = 0; $i < 150; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
                imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->heigh), '#', $color);
            }
        }

    画线条的时候,取比较深的颜色值,而画雪花的时候取比较淡的颜色值,目的是尽可能的不影响人眼识别验证码,又能干扰自动识别验证码机制。

    3.7对外生成验证码图像,供外部调用。

    //对外生成
        public function doImg()
        {
    
            $this->createBg();      //1.创建验证码背景
            $this->createCode();    //2.生成随机码
            $this->createLine();    //3.生成线条和雪花
            $this->createFont();    //4.生成文字
            $this->outPut();        //5.输出验证码图像
        }

    3.8完整代码:

    <?php
    
    /**
     * Created by PhpStorm.
     * User: andy
     * Date: 16-12-22
     * Time: 下午1:20
     */
    class ValidateCode
    {
        //随机因子
        private $charset = 'abcdefghjkmnprstuvwxyzABCDEFGJKMNPRSTUVWXYZ23456789';
        private $code;
        private $codeLen = 4;
    
        private $width = 130;
        private $heigh = 50;
        private $img;//图像
    
        private $font;//字体
        private $fontsize = 20;
    
    
        public function __construct()
        {
            $this->font = ROOT_PATH.'/font/Chowderhead.ttf';
            $this->img = imagecreatetruecolor($this->width, $this->heigh);
        }
    
        //生成随机码
        private function createCode()
        {
            $_len = strlen($this->charset) - 1;
            for ($i = 0; $i < $this->codeLen; $i++) {
                $this->code .= $this->charset[mt_rand(0, $_len)];
            }
        }
    
        //生成背景
        private function createBg()
        {
    
            $color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
            imagefilledrectangle($this->img, 0, $this->heigh, $this->width, 0, $color);
    
        }
    
        //生成文字
        private function createFont()
        {
            $_x = $this->width / $this->codeLen;
            $_y = $this->heigh / 2;
            for ($i = 0; $i < $this->codeLen; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
                imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(3, 5), $_y + mt_rand(2, 4), $color, $this->font, $this->code[$i]);
            }
        }
    
        //生成线条,雪花
        private function createLine()
        {
            for ($i = 0; $i < 15; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
                imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->heigh), mt_rand(0, $this->width), mt_rand(0, $this->heigh), $color);
            }
            for ($i = 0; $i < 150; $i++) {
                $color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
                imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->heigh), '#', $color);
            }
        }
    
        //输出图像
        private function outPut()
        {
            header('Content-Type: image/png');
            imagepng($this->img);
            imagedestroy($this->img);
        }
    
        //对外生成
        public function doImg()
        {
    
            $this->createBg();      //1.创建验证码背景
            $this->createCode();    //2.生成随机码
            $this->createLine();    //3.生成线条和雪花
            $this->createFont();    //4.生成文字
            $this->outPut();        //5.输出验证码图像
        }
    
        //获取验证码
        public function getCode()
        {
            return strtolower($this->code);
        }
    
    }
    class code:ValidateCode

    4.测试

      测试代码:

    <?php
    /**
     * Created by PhpStorm.
     * User: andy
     * Date: 16-12-22
     * Time: 下午1:20
     */
    
    define('ROOT_PATH', dirname(__FILE__));
    require_once ROOT_PATH.'/includes/ValidateCode.class.php';
    
    $_vc=new ValidateCode();
    echo $_vc->doImg();

    生成验证码:

    5.应用

    <label>
                <img src="../config/code.php" onclick="javascript:this.src='../config/code.php?tm='+Math.random();" />
            </label>

    上面onclick代码是点击验证码图片,能自动刷新验证码。

    code.php:

    <?php
    /**
     * Created by PhpStorm.
     * User: andy
     * Date: 16-12-22
     * Time: 下午3:43
     */
    require substr(dirname(__FILE__),0,-7).'/init.inc.php';
    
    $_vc=new ValidateCode();
    echo $_vc->doImg();
    $_SESSION['ValidateCode']=$_vc->getCode();
    View Code

    有关应用的完整代码可以从https://git.oschina.net/andywww/myTest 的CMS1.0 文件里下载。

    6.小结

        在独立测试过程,没发现什么问题;但应用到项目的时候,刚开始发现无法生成验证码图片,网上找了一下,有的说是在outPut()函数中,

    在   header('Content-Type: image/png'); 这行代码前面增加了一行ob_clean()代码,可以解决验证码这块问题。虽然此方法简单,但这可能会引起其他缓冲数据问题,因为db_clean()功能就是丢弃输出缓冲区中的内容。

  • 相关阅读:
    图数据库查询语言
    深入探索Spring Data JPA, 从Repository 到 Specifications 和 Querydsl
    axios 浏览器内存泄露问题解决
    给Swagger换一套皮肤 Knife4j集成记录
    根据经纬度和半径计算经纬度范围
    最火 Web 前端组态软件 (可视化)
    Python-----删除给定目录下的所有文件
    Python----发送邮件yagmail
    python------将"["1","2"]"类型是字符串,转换为["1","2"]类型为列表,即eval()用法
    python----自动生成requirements.txt与导入requirements.txt中的库
  • 原文地址:https://www.cnblogs.com/wghao/p/6213147.html
Copyright © 2020-2023  润新知