php实现的click captcha点击验证码类实例


Posted in PHP onSeptember 23, 2014

本文实例讲述了php实现的click captcha点击验证码类及其用法,是非常实用的功能。分享给大家供大家参考之用。具体如下:

一、需求:

现在常用的表单验证码大部分都是要用户输入为主,但这样对手机用户会不方便。
如果手机用户访问,可以不用输入,而是click某一位置便可确认验证码,这样就会方便很多。

二、原理:

1.使用PHP imagecreate创建PNG图象,在图中画N个圆弧,其中一个是完整的圆(验证用),将圆心坐标及半径记录入session。

2.在浏览器,当用户在验证码图片上点击时,记录点击的位置。

3.将用户点击的坐标与session记录的圆心坐标、半径比较,判断是否在圆中,如是则验证通过。

程序运行效果如下图所示:

php实现的click captcha点击验证码类实例

三、实现方法:

ClickCaptcha.class.php类文件如下:

<?php 
/** Click Captcha 验证码类 
*  Date:  2013-05-04 
*  Author: fdipzone 
*  Ver:  1.0 
*/ 
 
class ClickCaptcha { // class start 
 
  public $sess_name = 'm_captcha'; 
  public $width = 500; 
  public $height = 200; 
  public $icon = 5; 
  public $iconColor = array(255, 255, 0); 
  public $backgroundColor = array(0, 0, 0); 
  public $iconSize = 56; 
 
  private $_img_res = null; 
 
  public function __construct($sess_name=''){ 
    if(session_id() == ''){ 
      session_start(); 
    } 
 
    if($sess_name!=''){ 
      $this->sess_name = $sess_name; // 设置session name 
    } 
  } 
 
  /** 创建验证码 */ 
  public function create(){ 
 
    // 创建图象 
    $this->_img_res = imagecreate($this->width, $this->height); 
     
    // 填充背景 
    ImageColorAllocate($this->_img_res, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]); 
 
    // 分配颜色 
    $col_ellipse = imagecolorallocate($this->_img_res, $this->iconColor[0], $this->iconColor[1], $this->iconColor[2]); 
 
    $minArea = $this->iconSize/2+3; 
 
    // 混淆用图象,不完整的圆 
    for($i=0; $i<$this->icon; $i++){ 
      $x = mt_rand($minArea, $this->width-$minArea); 
      $y = mt_rand($minArea, $this->height-$minArea); 
      $s = mt_rand(0, 360); 
      $e = $s + 330; 
      imagearc($this->_img_res, $x, $y, $this->iconSize, $this->iconSize, $s, $e, $col_ellipse);       
    } 
 
    // 验证用图象,完整的圆 
    $x = mt_rand($minArea, $this->width-$minArea); 
    $y = mt_rand($minArea, $this->height-$minArea); 
    $r = $this->iconSize/2; 
    imagearc($this->_img_res, $x, $y, $this->iconSize, $this->iconSize, 0, 360, $col_ellipse);     
 
    // 记录圆心坐标及半径 
    $this->captcha_session($this->sess_name, array($x, $y, $r)); 
 
    // 生成图象 
    Header("Content-type: image/PNG"); 
    ImagePNG($this->_img_res); 
    ImageDestroy($this->_img_res); 
 
    exit(); 
  } 
 
  /** 检查验证码 
  * @param String $captcha 验证码 
  * @param int  $flag   验证成功后 0:不清除session 1:清除session 
  * @return boolean 
  */ 
  public function check($captcha, $flag=1){ 
    if(trim($captcha)==''){ 
      return false; 
    } 
     
    if(!is_array($this->captcha_session($this->sess_name))){ 
      return false; 
    } 
 
    list($px, $py) = explode(',', $captcha); 
    list($cx, $cy, $cr) = $this->captcha_session($this->sess_name); 
 
    if(isset($px) && is_numeric($px) && isset($py) && is_numeric($py) &&  
      isset($cx) && is_numeric($cx) && isset($cy) && is_numeric($cy) && isset($cr) && is_numeric($cr)){ 
      if($this->pointInArea($px,$py,$cx,$cy,$cr)){ 
        if($flag==1){ 
          $this->captcha_session($this->sess_name,''); 
        } 
        return true; 
      } 
    } 
    return false; 
  } 
 
  /** 判断点是否在圆中 
  * @param int $px 点x 
  * @param int $py 点y 
  * @param int $cx 圆心x 
  * @param int $cy 圆心y 
  * @param int $cr 圆半径 
  * sqrt(x^2+y^2)<r 
  */ 
  private function pointInArea($px, $py, $cx, $cy, $cr){ 
    $x = $cx-$px; 
    $y = $cy-$py; 
    return round(sqrt($x*$x + $y*$y))<$cr; 
  } 
 
  /** 验证码session处理方法 
  * @param  String  $name  captcha session name 
  * @param  String  $value 
  * @return String 
  */ 
  private function captcha_session($name,$value=null){ 
    if(isset($value)){ 
      if($value!==''){ 
        $_SESSION[$name] = $value; 
      }else{ 
        unset($_SESSION[$name]); 
      } 
    }else{ 
      return isset($_SESSION[$name])? $_SESSION[$name] : ''; 
    } 
  } 
} // class end 
 
?>

demo.php示例程序如下:

<?php 
session_start(); 
require('ClickCaptcha.class.php'); 
 
if(isset($_GET['get_captcha'])){ // get captcha 
  $obj = new ClickCaptcha(); 
  $obj->create(); 
  exit(); 
} 
 
if(isset($_POST['send']) && $_POST['send']=='true'){ // submit 
  $name = isset($_POST['name'])? trim($_POST['name']) : ''; 
  $captcha = isset($_POST['captcha'])? trim($_POST['captcha']) : ''; 
 
  $obj = new ClickCaptcha(); 
 
  if($obj->check($captcha)){ 
    echo 'your name is:'.$name; 
  }else{ 
    echo 'captcha not match'; 
  } 
  echo ' <a href="demo.php">back</a>'; 
 
}else{ // html 
?> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
 <head> 
 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
 <title> Click Captcha Demo </title> 
 <script type="text/javascript" src="jquery-1.6.2.min.js"></script> 
 <script type="text/javascript"> 
  $(function(){ 
    $('#captcha_img').click(function(e){ 
      var x = e.pageX - $(this).offset().left; 
      var y = e.pageY - $(this).offset().top; 
      $('#captcha').val(x+','+y); 
    }) 
 
    $('#btn').click(function(e){ 
      if($.trim($('#name').val())==''){ 
        alert('Please input name!'); 
        return false; 
      } 
 
      if($.trim($('#captcha').val())==''){ 
        alert('Please click captcha!'); 
        return false; 
      } 
      $('#form1')[0].submit(); 
    }) 
  }) 
 </script> 
 </head> 
 
 <body> 
  <form name="form1" id="form1" method="post" action="demo.php" onsubmit="return false"> 
  <p>name:<input type="text" name="name" id="name"></p> 
  <p>Captcha:Please click full circle<br><img id="captcha_img" src="demo.php?get_captcha=1&t=<?=time() ?>" style="cursor:pointer"></p> 
  <p><input type="submit" id="btn" value="submit"></p> 
  <input type="hidden" name="send" value="true"> 
  <input type="hidden" name="captcha" id="captcha"> 
  </form> 
 </body> 
</html> 
<?php } ?>

本文完整源码点击此处本站下载。

希望本文所述对大家的PHP程序设计有所帮助。

PHP 相关文章推荐
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
Jun 20 PHP
php5.3 注意事项说明
Jul 01 PHP
PHP数据库链接类(PDO+Access)实例分享
Dec 05 PHP
PHP中session变量的销毁
Feb 27 PHP
php将字符串全部转换成大写或者小写的方法
Mar 17 PHP
Codeigniter发送邮件的方法
Mar 19 PHP
PHP编译安装时常见错误解决办法
May 28 PHP
php实现将上传word文件转为html的方法
Jun 03 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
Oct 09 PHP
php验证码的制作思路和实现方法
Nov 12 PHP
PHP中的随机性 你觉得自己幸运吗?
Jan 22 PHP
thinkphp诸多限制条件下如何getshell详解
Dec 09 PHP
PHP实现自动登入google play下载app report的方法
Sep 23 #PHP
PHP遍历文件夹与文件类及处理类用法实例
Sep 23 #PHP
PHP邮件发送类PHPMailer用法实例详解
Sep 22 #PHP
php实现的CSS更新类实例
Sep 22 #PHP
php的XML文件解释类应用实例
Sep 22 #PHP
php实现的返回数据格式化类实例
Sep 22 #PHP
php实现的替换敏感字符串类实例
Sep 22 #PHP
You might like
服务器端解压缩zip的脚本
2006/12/22 PHP
php笔记之:AOP的应用
2013/04/24 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
PHP解析RSS的方法
2015/03/05 PHP
php实现微信公众号无限群发
2015/10/11 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
Ext JS Grid在IE6 下宽度的问题解决方法
2009/02/15 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
轻松学习jQuery插件EasyUI EasyUI表单验证
2015/12/01 Javascript
Javascript基础教程之比较null和undefined值
2016/05/16 Javascript
javascript获取select标签选中的值
2016/06/04 Javascript
JS简单实现tab切换效果的多窗口显示功能
2016/09/07 Javascript
js实现添加删除表格(两种方法)
2017/04/27 Javascript
js图片轮播插件的封装
2017/07/21 Javascript
详解EasyUi控件中的Datagrid
2017/08/23 Javascript
vue项目使用微信公众号支付总结及遇到的坑
2018/10/23 Javascript
vue router 组件的高级应用实例代码
2019/04/08 Javascript
解决layui动态加载复选框无法选中的问题
2019/09/20 Javascript
p5.js临摹动态图形的方法
2019/10/23 Javascript
vue实现鼠标移过出现下拉二级菜单功能
2019/12/12 Javascript
[14:56]教你分分钟做大人:巫医
2014/10/30 DOTA
整理Python最基本的操作字典的方法
2015/04/24 Python
Python matplotlib生成图片背景透明的示例代码
2019/08/30 Python
Python装饰器的应用场景代码总结
2020/04/10 Python
matplotlib 生成的图像中无法显示中文字符的解决方法
2020/06/10 Python
解决Keras自带数据集与预训练model下载太慢问题
2020/06/12 Python
BrandAlley英国:法国折扣奢侈品网上零售商
2017/07/03 全球购物
Unix/Linux开发面试题
2016/08/16 面试题
放弃继承权公证书
2015/01/23 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
运动会广播稿50字
2015/08/19 职场文书
python将图片转为矢量图的方法步骤
2021/03/30 Python
简单实现一个手持弹幕功能+文字抖动特效
2021/03/31 HTML / CSS
MySQL七种JOIN类型小结
2021/10/24 MySQL
MySQL数据库索引的最左匹配原则
2021/11/20 MySQL
解决Windows Server2012 R2 无法安装 .NET Framework 3.5
2022/04/29 Servers