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. 正确,投票成功;失败,提示错误