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();

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

6.小结

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

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

时间: 2024-10-12 17:05:35

PHP-解析验证码类--学习笔记的相关文章

Apache commons lang工具类学习笔记(2)--StringUtils

StringUtils工具类具有对String具有简单而强大的处理能力,从检查空串到分割字符串,到生成格式化的字符串,使用都很方便简洁,能减少很多代码量; 详细的使用方法可以参考下面的例子或者官方的API(http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html#isAlpha(java.lang.CharSequence)) packa

Java Object类学习笔记

看下Api文档的一些说明 public class Object Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class. Since: JDK1.0 从JDK1.0就已经存在的元老类,类结构的根,所有类的父类,所有类都实现了这个类的方法,包含

Collection类学习笔记

binarySearch原理: public static index halfSearch(List<String> list, String key) { int max,min,mid; max = list.size()-1; min = 0; while(min<=max) { mid = (max+min) >>1; String str = list.get(mid); int num = str.compareTo(key); if(num > 0) m

Arrays类学习笔记

Arrays.asList(arr); 该方法可以把数组变成List集合. String[] arr = {"abc","cc"}; List<String> list = Arrays.asList(arr); /* 如果数组中的元素都是对象,那么变成集合的时候,数组中的元素就直接转换成集合中的元素. 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在. */ Arrays.toArray(new String[]); 1. 指定类型

在MVC中使用dotless后台动态解析LESSCSS的学习笔记

通过学习LessCSS,我们知道,Less是需要通过编译才能生成 .css 文件,主要使用三种方式进行编译: 1)使用第三方编译工具,在项目发布前编译好放在项目中. 2)在浏览器端解析执行,需要引用 less.js . 3)使用第三方程序集在后台动态解析,例如:在.net平台下的dotless. 这篇随笔记录了如何在.net MVC项目中使用dotless动态解析less. 具体实现 1.创建MVC4 Web的基本项目 在 Content 文件夹中添加 lesses 文件夹,并在该文件夹下添加自

java.util.Properties类 学习笔记

学习目标: 1.认识properties文件,理解其含义,会正确创建properties文件. 2.会使用java.util.Properties类来操作properties文件. 3.掌握相对路径,能正确书写一个properties文件的相对路径. 一.认识properties文件 1.properties文件是一个文本文件 2.properties文件的语法有两种,一种是注释,一种属性配置. 注    释:前面加上#号 属性配置:以“键=值”的方式书写一个属性的配置信息. 3.propert

《C++ Primer Plus》10.2 抽象和类 学习笔记

10.2.1 类型是什么基本类型完成了下面的三项工作:* 决定数据对象需要的内存数量:* 决定如何解释内存中的位(long和float在内存中占用的位数相同,但是将它们转换为数值的方法不同):* 决定可以使用数据对象执行的操作或方法.在于内置类型来说,有关操作的信息被内置到编译器中.但在C++中定义用户自定义的类型时,必须自己提供这些信息.付出这些老动换来了根据实际需要定制新数据类型的强大功能和灵活性.10.2.2 C++中的类一般来说,类规范由两部分组成:* 类声明:以数据成员的方式描述数据部

C++类学习笔记

在C++中struct类型(结构体)属于类类型. class student {} 与 strcut student {}是一样的,唯一的区别就是class中如果未对成员进行public.private或protected等访问限定声明则默认为private的,而struct中则默认为public.类同样遵循结构体的字节对齐原则. 私有的成员函数只能被类内的其他成员函数调用,即使是其对象也不行.私有的成员变量只能被本类的成员函数和(友元类)所调用.友元类后续补充. 受保护的成员则可以被本类以及派

Java File类学习笔记2:File类对象及常用操作方法

一. 文件.相对路径与绝对路径 1.文件 (1)标准文件:就像图片,音乐文件等. (2)目录文件:也就是平常所说的文件夹. (3)虚拟内存文件:系统在运行程序时生成的临时性文件. 2.文件的路径 (1)相对路径:相对于某一文件的路径,形象地说是把两文件的绝对路径相同的部分砍掉,剩下的就是相对路径 如: A文件是"D:\MyDocuments\StudySample\src\cn\xmh", B文件是"D:\MyDocuments\StudySample\src\netjava