问题前言
面对复杂的网络情况,还是多给网站加条防线,来防止机器人注册垃圾评论等等。。
验证码,想必大家并不陌生吧,这是目前最常见的防御,所以今天给大家分享一段输出验证码的PHP代码
我这里写的是验证码图片输出和后端验证判断,对于前端显示,我这里暂时不写了,如果有需要可以评论,我再写给大家
解决方案
<?php /** * 验证码图片输出(支持中文/英文) */ // 封装验证码类 class Captcha{ // 定义属性 private $width; private $height; private $chars; // 随机字符长度 private $font; // 随机字体 private $lines; // 干扰线数量 private $pixels; // 干扰点数量 private $type; // 字符类型(中文或英文)1为中文,其他为英文 // 构造函数 public function __construct($arr=array()){ $this->width = isset($arr['width'])?$arr['width']:100; $this->height = isset($arr['height'])?$arr['height']:30; $this->chars = isset($arr['chars'])?$arr['chars']:4; $this->font = isset($arr['font'])?$arr['font']:5; $this->lines = isset($arr['lines'])?$arr['lines']:2; $this->pixels = isset($arr['pixels'])?$arr['pixels']:100; $this->type = isset($arr['type'])?$arr['type']:1; if($this->type==1){ $this->ChaineseCaptcha(); }else{ $this->generate(); } } // 生成画布以及干扰元素 public function makeBaseImage(){ // 基本画布 $image = imagecreatetruecolor($this->width, $this->height); // 画布颜色,随机获取 $color = imagecolorallocate($image, mt_rand(200,255), mt_rand(200,255), mt_rand(200,255)); // 画布填充 imagefill($image, 0, 0, $color); // 调用干扰线(点) 生成函数 // 生成干扰元素 $this->setLines($image); // 干扰线 $this->setPixel($image); // 干扰点 // 返回画布,供其他元素部分使用 return $image; } /** * 生成中文验证码 * @param string $ttfname 使用的中文字体 * @param recoure $image 图片资源 * @param return 中文验证码 * 我这里使用的是 simkai.ttf 字体,这个可以根据需求任意更换 */ public function ChaineseCaptcha($ttfname='./simkai.ttf'){ // 使用makeChainese得到的字符 // 生成画布 $image =$this->makeBaseImage(); // 在画布上写中文文字 // 文字颜色 $color = imagecolorallocate($image,mt_rand(0,100), mt_rand(0,100), mt_rand(0,100)); // 获取要操作的中文验证码文字 $captcha =$this->makeChainese(); // 开启sesssion @session_start(); $_SESSION['captcha'] = $captcha; // 画出文字 imagettftext($image, 16, 2, 10, 22, $color, $ttfname, $captcha); // 显示验证码 $this->show($image); // 销毁资源 imagedestroy($image); } /** 该环境是在 utf-8 下使用,若是gbk,请谨慎使用 * @param string $filename 保存的中文文字文件 * @return char_chainese * content_chainese.txt 我罗列了一些中文字符,这个可以根据需求自己修改 */ private function makeChainese($filename='./content_chainese.txt'){ $str = file_get_contents($filename); $captcha =''; for($i=0 ;$i<$this->chars;$i++){ $rand = mt_rand(0 ,strlen($str)-1); $rand = $rand-($rand%3); $captcha .=substr($str, $rand,3); } return $captcha; } /** * 生成验证码图片的方法 * @return 图片 */ public function generate(){ // 制作画布 $image =$this->makeBaseImage(); // 生成随机字符 $captcha = $this->setRandCaptcha($image ,$this->chars); // session 保存 session_start(); $_SESSION['captcha'] = $captcha; // 把字符串写入图片资源 // 颜色 $color = imagecolorallocate($image,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); imagestring($image ,$this->font ,30,8,$captcha ,$color); $this->show($image); // 释放图片资源 imagedestroy($image); } private function show($image){ header("content-type:image/png"); imagepng($image); } // 生成随机字符 private function setRandCaptcha(){ // 生成随机字符串 // $str =implode('' ,array_merge(range('1', '9'),range('a', 'z'),range('A', "Z"))); // 去掉了 0 1 O l 等 $str = "23456789ABCDEFGHJKLMNPQRSTUVYXZabcdefghkmnpqrstuvyxz"; // 得到随机字符串 $captcha =''; for($i=0 ;$i<$this->chars;$i++){ $captcha .=$str[mt_rand(0,strlen($str)-1)].''; } return $captcha; } // 增加干扰线 /** * @param resource $image */ private function setLines($image){ // 线的颜色 for($i=0 ; $i<$this->lines ;$i++){ $color = imagecolorallocate($image, mt_rand(100,150), mt_rand(100,150), mt_rand(100,150)); imageline($image, mt_rand(0,$this->width), mt_rand(0,$this->height), mt_rand(0,$this->width), mt_rand(0,$this->height), $color); } } /** * 增加像素点 * @return 返回点 */ private function setPixel($image){ // 循环画点 for($i=0;$i<$this->pixels;$i++){ $color=imagecolorallocate($image,mt_rand(150,200), mt_rand(150,200), mt_rand(150,200)); // 生成点 imagesetpixel($image, mt_rand(0,$this->width), mt_rand(0,$this->height), $color); } } /** * 增加验证方法 * @param string $captcha 用户输入的验证码 * @return boolean */ public static function compareCaptcha($captcha){ // 比较,不区分大小写 // 开启session session_start(); return strtolower($captcha)===strtolower($_SESSION['captcha']); } } // 输出验证码(type=1为中文,其他为英文) $c = new Captcha(array('type'=>1));
运行后:
使用说明
请根据自己实际情况做相应修改
源码下载
隐藏内容需要回复可以看见
回复
楼主辛苦了,谢谢楼主,楼主好人一生平安!