PHP生成验证码图片

赶紧来总结一下自己的小知识,啊~~ 我还活着

最近做了一个投票活动,但有人刷票,就让主办方头疼了,上级让我加一个手机短信验证,就增加了刷票人的成本嘛,第一天完成了手机短信验证功能,但第二天就让我改...  改成 PHP生成验证码,就取消手机短信了

 

哼哼,我居然一点都不慌~ 

 

因为刚做了手机短信验证,是将验证码记录在数据库里的,所以我们的程序生成验证码,我也记录在数据库里了,这是我的设计模式,目的呢,是能记录下来,哪些用户,在什么时间段,获取了验证码,是否使用了等等信息。。

 

我用的是原生PHP,没有用ThinkPHP等框架。因为我们公司有自己的框架,但比较古老,已经out了,正在转TP5

 

完成PHP验证码,很简单:

/**
     * 生成随机数字验证码
     *
     * @param int $size 验证码长度
     *
     * @return string
     */
    function generateRandNumberVerificationCode($size = 4)
    {
        if($size <= 0 || empty($size) || !isset($size))
        {
            $size = 4;
        }

        //验证码内容
        $code_array = array(
            0,1,2,3,4,5,6,7,8,9
        );

        $random_keys = array();
        for($i = 0; $i < $size; $i++)
        {
            $keys = array_rand($code_array,1);

            array_push($random_keys,$code_array[$keys]);
        }

        //数组转成字符串
        $verification_code = implode('',$random_keys);

        return $verification_code;

    }

  

上面是我自己写的一个,嗯....里面只有 0-9的数字,如果你想用 a-z 这种,就在 $code_array 数组里加入即可。

封装的这个方法,个人觉得还是很简单,易懂,最后返回获取到的 4位数验证码。 你在外面调用时,可以传入$size,$size=6 就代表是6位验证码,默认是4位

 

我们调用这个方法,获取到验证码,然后就将这个验证码保存在数据库里,再写个接口给前端调用,就完成啦~  注:验证码记录到数据库时,同时记录是哪个用户在操作,操作时间,验证码过期时间,这是我的设计模式

emmmm最开始我是这么想的

 

但前端有点懵,因为我的想法是,接口返回一组字符串,前端收到了,不能就直接显示出来,那多难看啊,肯定要加样式,我想的是给前端处理,让他想个办法,组个图片,或者打乱样式,但好像有点难, 最后商量了一下,让我PHP在后台生成一张图片传给前端, 也就是验证码图片

 

有很多小伙伴不明白验证码图片,因为是图片,用户提交的是字符串,怎么和图片做对比? 以前我也是这么想的。。 其实,上面我就写了,已经生成了一组验证码,记录到数据库了,明白了吗。  用户输入的字符串,最后做比较的,不是图片,而是和我已经生成的验证码, 图片,只是用来给用户看的, 而这个图片的内容,就是我来定义

 

以下是生成 验证码图片代码:

/**
     * 生成随机数字验证码图片
     *
     * @param string $code 验证码内容
     *
     * @param string $member_id 会员id
     *
     * @param string $width 图片宽度
     *
     * @param string $height 图片宽度
     *
     * @return string
     */
    function generateRandNumberVerificationCodeImg($code = '',$member_id = '',$width = 80,$height = 40)
    {
        if(empty($code) || !isset($code))
        {
            return false;
        }
        if(empty($member_id) || !isset($member_id))
        {
            return false;
        }

        //判断文件夹是否存在,不存在则创建
        $dir = ROOT_PATH.'/upload/verification_code_img';
        if(!is_dir($dir)){
            mkdir($dir, 0777, true);
        }

        //验证码图片保存路径,文件名称
        $file_name = ROOT_PATH.'/upload/verification_code_img/member_id_'.$member_id.'.png';
        //域名返回
        $domain_name = _constant_url.'/upload/verification_code_img/member_id_'.$member_id.'.png';

        $img = imagecreatetruecolor($width, $height);
        $black = imagecolorallocate($img, 0x00, 0x00, 0x00);
        $green = imagecolorallocate($img, 0x00, 0xFF, 0x00);
        $white = imagecolorallocate($img, 0xFF, 0xFF, 0xFF);
        imagefill($img,0,0,$white);

        imagestring($img, 5, 22, 12, $code, $black);
        //加入噪点干扰
        for($i=0;$i<100;$i++) {
            imagesetpixel($img, rand(0, $width) , rand(0, $width) , $black);  //imagesetpixel — 画一个单一像素,语法: bool imagesetpixel ( resource $image , int $x , int $y , int $color )
            imagesetpixel($img, rand(0, $width) , rand(0, $width) , $green);
        }

        //输出验证码
//        header("content-type: image/png");
        imagepng($img,$file_name);  //保存图片
        imagedestroy($img);  //图像处理完成后,使用 imagedestroy() 指令销毁图像资源以释放内存,虽然该函数不是必须的,但使用它是一个好习惯。

        return $domain_name;
    }

  

以上代码需要注意的是:

1. 我这边定义的常量,可能和你们的不同,但基本是国际命名法,大致应该都能明白变量或常量的意思

2. $code 这个参数是验证码内容,就是我先生成了验证码,然后调用这个生成图片,将验证码传了进去,图片里就是我的验证码内容了

3. 方法里最后两个参数:$width 和 $height,这两个参数,是用来定义你的图片宽和高的

4. imagestring() 方法,我在里面写的是绝对值,4位数验证码就合适,但6位,8位,或者其他的,样式就不好看了,小伙伴有兴趣可以写一个数学运算,这样传几位验证码,都能保证在图片中间,以及好看的样式。emmmmm以前写过百分比,各种计算,但这次就算啦

5. 这里生成的图片,你一定要去学习 PHP GD库,可以直接百度"PHP GD库"

 

验证码图片这个方法,我是将图片保存在我的项目里,以及取出它的域名链接,保存在数据库里,这样我就可以传给前端,前端来获取这个验证码的图片了。  用户看到这个图片的内容,输入字符串,后台进行验证,结束。

 

 

以下是我本次处理验证码功能的逻辑:

1. 生成验证码

2. 根据验证码,生成 验证码图片

3. 保存至数据库,记录验证码、当前用户、创建时间、过期时间、是否已验证、验证码图片路径

4. 写接口,传给前端 验证码图片

5. 前端展示图片给用户

6. 用户根据验证码图片输入 验证码内容

7. 前端确认用户输入信息,传给接口

8. PHP接口做处理,验证用户输入的验证码内容是否正确

9. 正确,投票成功;失败,提示错误

 

posted on 2019-04-27 17:37  幸享龙枫  阅读(3890)  评论(1编辑  收藏  举报

导航