PHP生成验证码类 | PHP折腾记

  • 2018-09-17
  • 412
  • 5

本次分享的是站长在学习PHP过程中的一个实战demo–** 生成验证码类 **

首先来说一下需要的成员属性

需要的成员属性有: 验证码个数 , 验证码类型 , 输出图像的宽度,高度 , 图像资源 以及 验证码字符串

我们首先声明如下成员属性, 这些属性我们都把他设为protected

#验证码个数
protected $number;
#验证码类型
protected $codeType;
#图像宽度
protected $width;
#图像高度
protected $height;
#图像资源
protected $image;
#验证码字符串
protected $code;

接下来我们需要初始化成员属性, 使用构造函数  同时在构造函数最后调用生成验证码函数(此时验证码只是一个字符串)–此函数后面会解说

传入的参数有 验证码个数 , 验证码类型  , 图像宽度 高度

public function __construct($number = 4 , $codeType = 2 , $width = 100, $height = 50) {
    //初始化成员属性
    $this>;number = $number;
    $this->codeType = $codeType;
    $this->width = $width;
    $this->height = $height;
    //生成验证码函数
    $this->code = $this->createCode();
}

下面是生成验证码函数的实现,由于函数只在类内部使用,这里我们把它设置为 protected

我们根据验证码类型去生成不同的验证码

$codeType  0为纯数字验证码  1为纯字母验证码  2为字母数字混合验证码

protected function createCode(){
        switch($this->codeType){
            case 0:
                //纯数字
                $code = $this->getNumberCode();
                break;
            case 1:
                //纯字母
                $code = $this->getCharCode();
                break;
            case 2:
                //字母数字混合
                $code = $this->getNumCharCode();
                break;
            default:
                die('不支持这种验证码类型');
        }
        return $code;
    }

以下是纯数字验证码生成 getNumberCode() 同样设为protected

protected function getNumberCode(){
        $str = join('' , range(0,9));
        return substr(str_shuffle($str) , 0 , $this->number);
    }

其中$str = join('' , range(0,9));是生成一个0-9的字符串, 通过str_shuffle($str)将其顺序随机打乱,substr(str_shuffle($str) , 0 , $this->number) 则是截取其0 - $this->number长度的字符串,$this->number是我们在构造方法中设置的,默认为4

接下来是纯字母验证码函数的实现

protected function getCharCode(){
        $str = join('' , range('a','z'));
        $str = $str . strtoupper($str);
        return substr(str_shuffle($str) , 0 , $this->number);
    }

字母数字混合的验证码生成函数

protected function getNumCharCode(){
    $numStr = join('' , range(0,9));
    $str = join('' , range('a','z'));
    $str = $numStr . $str . strtoupper($str);
    return substr(str_shuffle($str) , 0 , $this->number);
}

原理与上面两个函数类似,不再赘述.

到此,我们可以调用createCode()方法生成一个随机的验证码字符串.

当然只有字符串是远远不够的,下面我们来看看如何生成验证码图片

我们来实现一个public方法供已外部调用生成验证码图片

public function outImage(){
        //创建画布
        $this->createImage();
        //填充背景色
        $this->fillBack();
        //画验证码于画布
        $this->drawChar();
        //添加干扰元素
        $this->drawDisturb();
        //输出 显示
        $this->show();
    }

首先我们需要创建画布
将画布的宽度高度设置我们我们成员属性的$width, $height

protected function createImage(){
    $this->image = imagecreatetruecolor($this->width , $this->height);
}

接下来我们去给图像填充背景颜色, 由于需要让验证码能够让用户看清  我们需要将背景颜色设为浅色

下面是生成浅色和深色的方法  ,   浅色用于背景   深色用于验证码 和 干扰元素

protected function lightColor(){
    return imagecolorallocate($this->image , mt_rand(130,255) , mt_rand(130,255) , mt_rand(130,255));
}

protected function darkColor(){
    return imagecolorallocate($this->image , mt_rand(0,120) , mt_rand(0,120) , mt_rand(0,120));
    }

imagecolorallocate()这个方法我们可以通过查询PHP文档了解如何使用

下面实现背景颜色填充,使用imagefill()方法

protected function fillBack(){
    imagefill($this->image , 0 , 0 , $this->lightColor());
}

接下来是我们重要的一个方法  将验证码画入画布

protected function drawChar(){
    $width = ceil($this->width / $this->number);
    for ($i = 0 ; $i < $this->number ; $i++){
            $x = mt_rand($width * $i + 5, $width * ($i + 1) - 10);
            $y = mt_rand(0 , $this->height - 15);
            imagechar($this->image , 5 , $x , $y , $this->code[$i] , $this->darkColor());
    }
}

我们使用$width = ceil($this->width / $this->number); 设置一下一个验证码的单位宽度 ,  然后用循环将验证码写入画布

下面我们往画布中填充干扰元素
使用imagesetpixel()方法画干扰点, 通过mt_rand()方法生成单个点的位置

使用imagearc()方法画入弧线, 同样使用mt_rand()方法生成 圆心,半径等

protected function drawDisturb(){
    for($i = 0 ; $i < 150 ; $i++){
        $x = mt_rand(0 , $this->width);
        $y = mt_rand(0 , $this->height);
        imagesetpixel($this->image , $x , $y , $this->lightColor);
    }
    for ($i = 0 ; $i < $this->number ; $i++){
        imagearc($this->image, mt_rand(10,$this->width) , mt_rand(10,$this->height) ,
        mt_rand(10,$this->width), mt_rand(10,$this->height) , mt_rand(0,10),mt_rand(0,270),$this->darkColor($this->image));
    }
}

最后声明资源类型

protected function show(){
    header('Content-Type:image/png');
    imagepng($this->image);
}

还有一个重要的地方, 验证码用于验证 我们需要将验证码返回, 这里我们使用一个魔术方法

public function __get($name){
    if ($name == 'code') {
        return $this->code;
    }
    return false;
}

然后我们实例化对象  VerifyCode是我们类名

$verifyCode = new VerifyCode();
//输出图像
$verifyCode->outImage();
//得到验证码
$verifyCode->getCode();

最后是本次demo的下载链接

链接:https://pan.baidu.com/s/1eQfRlyZnE2XWn5mNAXAPWA 密码:ackn

评论

  • 疯帽子回复

    狗屎

    • 燕归来回复

      傻媳妇(滑稽)

      • Yeshisan回复

        整个博客就你们两条评论,尴尬不。

        • 燕归来回复

          丝毫不慌

  • 呵呵哒回复

    就不能直接整个弄好打包 😕