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 相关文章推荐
PHP 数组教程 定义数组
Oct 23 PHP
PHP 图片上传代码
Sep 13 PHP
php数组函数序列之array_sum() - 计算数组元素值之和
Oct 29 PHP
解析zend Framework如何自动加载类
Jun 28 PHP
php类常量用法实例分析
Jul 09 PHP
PHP中PDO的事务处理分析
Apr 07 PHP
PHP学习笔记之php文件操作
Jun 03 PHP
php获取开始与结束日期之间所有日期的方法
Nov 29 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
PHP设计模式之委托模式定义与用法简单示例
Aug 13 PHP
Thinkphp5 如何隐藏入口文件index.php(URL重写)
Oct 16 PHP
禁止直接访问php文件代码分享
May 05 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
php 用sock技术发送邮件的函数
2007/07/21 PHP
php+mysql 实现身份验证代码
2010/03/24 PHP
php更新mysql后获取影响的行数发生异常解决方法
2013/03/28 PHP
php实现cookie加密的方法
2015/03/10 PHP
WordPress中重置文章循环的rewind_posts()函数讲解
2016/01/11 PHP
Symfony2学习笔记之插件格式分析
2016/03/17 PHP
PHP Yaf框架的简单安装使用教程(推荐)
2016/06/08 PHP
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
jquery弹出框的用法示例(2)
2013/08/26 Javascript
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
2020/09/13 Javascript
js实现本地图片文件拖拽效果
2017/07/18 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
Vue函数式组件-你值得拥有
2019/05/09 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
jQuery实现轮播图效果
2019/11/26 jQuery
vue-resourc发起异步请求的方法
2020/02/11 Javascript
Vue表单提交点击事件只允许点击一次的实例
2020/10/23 Javascript
[48:47]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python基础教程之对象和类的实际运用
2014/08/29 Python
Python中isnumeric()方法的使用简介
2015/05/19 Python
python中函数传参详解
2016/07/03 Python
Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS浅析
2018/05/08 Python
Python基础学习之函数方法实例详解
2019/06/18 Python
django rest framework serializers序列化实例
2020/05/13 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
怀俄明州飞钓:Platte River Fly Shop
2017/12/28 全球购物
好书伴我成长演讲稿
2014/05/14 职场文书
2014年客服工作总结范文
2014/11/13 职场文书
个人业务学习心得体会
2016/01/25 职场文书
祝福语集锦:送给毕业同学祝福语
2019/11/21 职场文书
pandas求平均数和中位数的方法实例
2021/08/04 Python
Android自定义双向滑动控件
2022/04/19 Java/Android