当前位置:首页 > CMS教程 > Thinkphp > 列表

ThinkPHP 3.2.3实现加减乘除图片验证码

发布:smiling 来源: PHP粉丝网  添加日期:2021-11-02 09:59:37 浏览: 评论:0 

ThinkPHP 3.2.3 自带的验证码类位于 /ThinkPHP/Library/Think/Verify.class.php,字体文件位于 /ThinkPHP/Library/Think/Verify/

可以在 Verify.class.php 文件内进行修改,也可以单独写一个类继承自带的验证码类。如果单独写一个继承的类,可以重用父类的属性和方法,但是要注意的是父类中有一些属性和方法是私有(private)的,可以修改这些私有的属性和方法为保护(protected)的,如果不希望修改框架自带的方法的话,也可以在子类中再定义这些属性和方法。

测试的控制器位于 /Application/Home/Controller/TestVerifyController.class.php

测试的试图位于 /Application/Home/View/User/verify.html

自定义的子类位于 /Applicaion/Home/Common/VerifyProcess.class.php

VerifyProcess.class.php:

  1. <?php 
  2.    
  3. namespace Home\Common; 
  4. use Think\Verify; 
  5.    
  6. class VerifyProcess extends Verify { 
  7.    
  8.  private $_image = NULL;  // 验证码图片实例 
  9.  private $_color = NULL;  // 验证码字体颜色 
  10.    
  11.  public function entryProcess($id = '') { 
  12.  // 图片宽(px) 
  13.  $this->imageW || $this->imageW = $this->length*$this->fontSize*1.5 + 
  14.  $this->length*$this->fontSize/2; 
  15.  // 图片高(px) 
  16.  $this->imageH || $this->imageH = $this->fontSize * 2.5; 
  17.  // 建立一幅 $this->imageW x $this->imageH 的图像 
  18.  $this->_image = imagecreate($this->imageW, $this->imageH); 
  19.    
  20.  // 设置背景   
  21.  imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); 
  22.    
  23.  // 验证码字体随机颜色 
  24.  $this->_color = imagecolorallocate($this->_image, mt_rand(1,150),  
  25.  mt_rand(1,150), mt_rand(1,150)); 
  26.  // 验证码使用随机字体 
  27.  $ttfPath = $_SERVER['DOCUMENT_ROOT'].'/ThinkPHP/Library/Think/Verify/' .  
  28.  ($this->useZh ? 'zhttfs' : 'ttfs') . '/'
  29.    
  30.  if(emptyempty($this->fontttf)){ 
  31.   $dir = dir($ttfPath); 
  32.   $ttfs = array();   
  33.   while (false !== ($file = $dir->read())) { 
  34.    if($file[0] != '.' && substr($file, -4) == '.ttf') { 
  35.     $ttfs[] = $file
  36.    } 
  37.   } 
  38.   $dir->close(); 
  39.   $this->fontttf = $ttfs[array_rand($ttfs)]; 
  40.  } 
  41.  $this->fontttf = $ttfPath . $this->fontttf; 
  42.     
  43.  if($this->useImgBg) { 
  44.   $this->_background(); 
  45.  } 
  46.     
  47.  if ($this->useNoise) { 
  48.   // 绘杂点 
  49.   $this->_writeNoise(); 
  50.  } 
  51.  if ($this->useCurve) { 
  52.   // 绘干扰线 
  53.   $this->_writeCurve(); 
  54.  } 
  55.     
  56.  // 绘验证码 
  57.  $codeNX = 0; // 验证码第N个字符的左边距 
  58.    
  59.  // 验证码为简单运算 
  60.  $a = mt_rand(1,9); 
  61.  $b = mt_rand(1,9); 
  62.  $operate_array = array('+''-''*'); 
  63.  $key = mt_rand(0, count($operate_array) - 1); 
  64.     
  65.  if($operate_array[$key] == '+') { // 加法 
  66.   $code = $a.'+'.$b.'='
  67.   $result = intval($a + $b); 
  68.  } elseif($operate_array[$key] == '-') { // 减法 
  69.   $code = max($a,$b).'-'.min($a,$b).'='
  70.   $result = intval(abs($a - $b)); 
  71.  } else { // 乘法 
  72.   $code = $a.'*'.$b.'='
  73.   $result = intval($a * $b); 
  74.  } 
  75.    
  76.  $this->length = 4; 
  77.    
  78.  for ($i = 0; $i<$this->length; $i++) { 
  79.   $codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6); 
  80.   imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40),  
  81.   $codeNX$this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]); 
  82.  } 
  83.    
  84.  // 保存验证码 
  85.  $key  = $this->authcode($this->seKey); 
  86.  $result  = $this->authcode($result); 
  87.  $secode  = array(); 
  88.  $secode['verify_code'] = $result// 把校验码保存到session 
  89.  $secode['verify_time'] = NOW_TIME; // 验证码创建时间 
  90.  session($key.$id$secode); 
  91.     
  92.  header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate'); 
  93.  header('Cache-Control: post-check=0, pre-check=0', false);   
  94.  header('Pragma: no-cache'); 
  95.  header("content-type: image/png"); 
  96.    
  97.  // 输出图像 
  98.  imagepng($this->_image); 
  99.  imagedestroy($this->_image); 
  100.  } 
  101.    
  102.  /** 
  103.  * 画杂点 
  104.  * 往图片上写不同颜色的字母或数字 
  105.  */ 
  106.  private function _writeNoise() { 
  107.   $codeSet = '2345678abcdefhijkmnpqrstuvwxyz'
  108.   for($i = 0; $i < 10; $i++){ 
  109.    //杂点颜色 
  110.    $noiseColor = imagecolorallocate($this->_image, mt_rand(150,225),  
  111.    mt_rand(150,225), mt_rand(150,225)); 
  112.    for($j = 0; $j < 5; $j++) { 
  113.     // 绘杂点 
  114.     imagestring($this->_image, 5, mt_rand(-10, $this->imageW),  
  115.    mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); 
  116.    } 
  117.   } 
  118.  } 
  119.    
  120.  /** 
  121.  * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) 
  122.  *   
  123.  *  高中的数学公式咋都忘了涅,写出来 
  124.  *  正弦型函数解析式:y=Asin(ωx+φ)+b 
  125.  *  各常数值对函数图像的影响: 
  126.  *  A:决定峰值(即纵向拉伸压缩的倍数) 
  127.  *  b:表示波形在Y轴的位置关系或纵向移动距离(上加下减) 
  128.  *  φ:决定波形与X轴位置关系或横向移动距离(左加右减) 
  129.  *  ω:决定周期(最小正周期T=2π/∣ω∣) 
  130.  * 
  131.  */ 
  132.  private function _writeCurve() { 
  133.  $px = $py = 0; 
  134.     
  135.  // 曲线前部分 
  136.  $A = mt_rand(1, $this->imageH/2);     // 振幅 
  137.  $b = mt_rand(-$this->imageH/4, $this->imageH/4); // Y轴方向偏移量 
  138.  $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 
  139.  $T = mt_rand($this->imageH, $this->imageW*2); // 周期 
  140.  $w = (2* M_PI)/$T
  141.         
  142.  $px1 = 0; // 曲线横坐标起始位置 
  143.  $px2 = mt_rand($this->imageW/2, $this->imageW * 0.8); // 曲线横坐标结束位置 
  144.    
  145.  for ($px=$px1$px<=$px2$px = $px + 1) { 
  146.   if ($w!=0) { 
  147.    $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;  
  148.    // y = Asin(ωx+φ) + b 
  149.    $i = (int) ($this->fontSize/5); 
  150.    while ($i > 0) { 
  151.     imagesetpixel($this->_image, $px + $i , $py + $i$this->_color);  
  152.     // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出 
  153.     (不用这while循环)性能要好很多    
  154.     $i--; 
  155.    } 
  156.   } 
  157.  } 
  158.     
  159.  // 曲线后部分 
  160.  $A = mt_rand(1, $this->imageH/2);     // 振幅  
  161.  $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 
  162.  $T = mt_rand($this->imageH, $this->imageW*2); // 周期 
  163.  $w = (2* M_PI)/$T;   
  164.  $b = $py - $A * sin($w*$px + $f) - $this->imageH/2; 
  165.  $px1 = $px2
  166.  $px2 = $this->imageW; 
  167.    
  168.  for ($px=$px1$px<=$px2$px=$px+ 1) { 
  169.   if ($w!=0) { 
  170.    $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;  
  171.    // y = Asin(ωx+φ) + b 
  172.    $i = (int) ($this->fontSize/5); 
  173.    while ($i > 0) {   
  174.     imagesetpixel($this->_image, $px + $i$py + $i$this->_color);  
  175.     $i--; 
  176.    } 
  177.   } 
  178.  } 
  179.  } 
  180.    
  181.  /* 加密验证码 */ 
  182.  private function authcode($str){ 
  183.  $key = substr(md5($this->seKey), 5, 8); 
  184.  $str = substr(md5($str), 8, 10); 
  185.  return md5($key . $str); 
  186.  }  
  187.    
  188.  /** 
  189.  * 绘制背景图片 
  190.  * 注:如果验证码输出图片比较大,将占用比较多的系统资源 
  191.  */ 
  192.  private function _background() { 
  193.   $path = dirname(__FILE__).'/Verify/bgs/'
  194.   $dir = dir($path); 
  195.    
  196.   $bgs = array();   
  197.   while (false !== ($file = $dir->read())) { 
  198.    if($file[0] != '.' && substr($file, -4) == '.jpg') { 
  199.     $bgs[] = $path . $file
  200.    } 
  201.   } 
  202.   $dir->close(); 
  203.    
  204.   $gb = $bgs[array_rand($bgs)]; 
  205.    
  206.   list($width$height) = @getimagesize($gb); 
  207.   // Resample 
  208.   $bgImage = @imagecreatefromjpeg($gb); 
  209.   @imagecopyresampled($this->_image, $bgImage, 0, 0, 0, 0, $this->imageW,  
  210.   $this->imageH, $width$height); 
  211.   @imagedestroy($bgImage); 
  212.  }  
  213. }

TestVerifyController.class.php:

  1. <?php 
  2. namespace Home\Controller; 
  3. use Think\Controller; 
  4. use Home\Common\VerifyProcess; 
  5.    
  6. class TestVerifyController extends Controller { 
  7.    
  8.  // 界面 
  9.  public function index() { 
  10.   $this->display('User/verify'); 
  11.  } 
  12.    
  13.  // 验证 
  14.  public function check_verify() { 
  15.      
  16.   $verify = new VerifyProcess(); 
  17.  if(!$verify->check($_POST['verify'])) { 
  18.   $this->error('验证码错误'); 
  19.  } 
  20.  } 
  21.    
  22.  // 显示验证码 
  23.  public function verify() { 
  24.    $verify = new VerifyProcess(); 
  25.    $verify->entryProcess(); 
  26.  }  

verify.html:

  1. <!DOCTYPE html> 
  2. <html lang="en"> 
  3. <head> 
  4.  <meta charset="UTF-8"> 
  5.  <title>Document</title> 
  6.  <script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script> 
  7. </head> 
  8. <body> 
  9.  <form action="{:U('Home/TestVerify/check_verify','','')}" method="post"> 
  10.   <table> 
  11.    <tr> 
  12.     <td>验证码:</td> 
  13.     <td><input type="text" name="verify"></td> 
  14.     <td> 
  15.      <img id="verify" src="{:U('Home/TestVerify/verify','','')}" 
  16.      style="cursor: pointer;" alt=""> 
  17.      <a id="refresh" href="javascript:void(0)" rel="external nofollow" >更换验证码</a> 
  18.     </td> 
  19.    </tr> 
  20.    <tr> 
  21.     <td colspan="2"> 
  22.      <input type="submit" value="提交"> 
  23.     </td> 
  24.    </tr> 
  25.   </table> 
  26.  </form> 
  27. </body> 
  28. <script> 
  29.  $(function(){ 
  30.    
  31.   $src = $("#verify").attr('src'); 
  32.    
  33.   $("#refresh").click(function(){ 
  34.    change_verify(); 
  35.   });  
  36.    
  37.   $("#verify").click(function(){ 
  38.    change_verify(); 
  39.   }); 
  40.    
  41.   function change_verify() { 
  42.    $('#verify').attr('src', $src + '?' + Math.random()); 
  43.   } 
  44.  }); 
  45.    
  46. </script> 
  47. </html>

Tags: ThinkPHP3 2 3验证码

分享到: