PHP图片验证码的实现-包括前后台页面

        以前输出验证码的时候用过一个方法,在前台用JS生成验证码字符串,再传递到后台用PHP输出验证码图像。这样在验证时就不需要使用$_SESSION传递验证码的值,直接用JS比较生成的字符串和输入的字符串是否相等即可。

        但是这种方法的缺点是结构化编程比较明显,并且感觉脱节比较严重。在网上找了一些生成验证码的方法,也都不太完整,有些只包括生成图像并没有包括完整的验证部分,因此在此给出完整的验证码生成类和验证过程。


index.php

其中<img src="ValidationCode.class.php" id="checkImg">用于输出验证码图像。checkImg.οnclick=function() { checkImg.src="ValidationCode.class.php?num="+Math.random();  } 用于在单击时重新加载图像

 <?php
 session_start();                                   //用于在$_SESSION中获取验证码的值
?>
<script type="text/javascript">
 window.οnlοad=function() {
  var xmlHttp = false;
  if (window.XMLHttpRequest) {      //Mozilla、Safari等浏览器
   xmlHttp = new XMLHttpRequest();
  }
  else if (window.ActiveXObject) {    //IE浏览器
   try {
    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
   } catch (e) {
    try {
     xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
   }
  }
  var checkImg=document.getElementById("checkImg");
  var checkCode=document.getElementById("checkCode");
  checkImg.οnclick=function() {
   checkImg.src="ValidationCode.class.php?num="+Math.random();  //以下用於单击验证码时重新加载验证码图片
   //需要加num=Math.random()以防止图片在本地缓存,单击图片时不刷新显示
  }
  checkCode.οnblur=function(){
   //alert("Hello");
   xmlHttp.open("POST","checkCode.php",true);
   xmlHttp.onreadystatechange=function () {
    if(xmlHttp.readyState==4 && xmlHttp.status==200) {
     var msg=xmlHttp.responseText;    //设置标志用于表示验证码是否正确
     if(msg=='1')
      document.getElementById("checkResult").innerHTML="正确";  //在这可以设置其中间显示一张图片
     else
      document.getElementById("checkResult").innerHTML="错误";
    }
   }
   xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
   xmlHttp.send("validateCode="+checkCode.value);
  } 
 }
</script>
<input type="text" id="checkCode">
<img src="ValidationCode.class.php" id="checkImg"><span id="checkResult">请在此输入验证码</span>


ValidationCode.class.php

验证码的生成类,要使用$_SESSION['checkCode']将验证码的值存入$_SESSION中。

<?php
session_start();               //为了将验证码的值保留在$_SESSION中
class ValidationCode {
 private $width;
 private $height;
 private $codeNum;           //验证码的个数
 private $image;             //图像资源
 private $checkCode;         //验证码字符串

 function __construct($width=60,$height=20,$codeNum=4) {
  $this->width=$width;
  $this->height=$height;
  $this->codeNum=$codeNum;
  $this->checkCode=$this->createCheckCode();
 }
 //通过调用该方法向浏览器输出验证码图像
 function showImage() {
  $this->createImage();      //第一步:创建背景图像
  $this->setDisturbColor();  //第二步:设置干扰元素,此处只加了干扰直线
  $this->outputText();       //第三步:输出验证码
  $this->outputImage();      //第四步:输出图像
 }
 //通过调用该方法获取随机创建的验证码字符串
 function getCheckCode(){
  return $this->checkCode;
 }
 //创建背景图像
 private function createImage(){
  $this->image=imagecreatetruecolor($this->width, $this->height);
  //随机背景色
  $backColor=imagecolorallocate($this->image, rand(225,255), rand(225,255), rand(225,255));
  //为背景填充颜色
  imagefill($this->image, 0, 0, $backColor);
  //设置边框颜色
  $border=imagecolorallocate($this->image, 0, 0, 0);
  //画出矩形边框
  imagerectangle($this->image, 0, 0, $this->width-1, $this->height-1, $border); 
 }
 //输出干扰元素
 private function setDisturbColor() {
  $lineNum=rand(2,4);               //设置干扰线数量
  for($i=0;$i<$lineNum;$i++) {
   $x1=rand(0,$this->width/2);
   $y1=rand(0,$this->height/2);
   $x2=rand($this->width/2,$this->width);
   $y2=rand($this->height/2,$this->height);
   $color=imagecolorallocate($this->image, rand(100,200), rand(100,200), rand(100,200));   //颜色设置比背景深,比文字浅
   imageline($this->image, $x1, $y1, $x2, $y2, $color);
  }
 }
 //生成验证码字符串
 private function createCheckCode() {    //或者这里可以通过前台传递过来的参数生成字符
  $code="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  $string="";
  for($i=0;$i<$this->codeNum;$i++) {
   $char=$code{rand(0,strlen($code)-1)};
   $string.=$char;
  }
  return $string;
 }
 //输出验证码
 private function outputText() {
  //echo "<script type='text/javascript'>alert('".$this->checkCode."')</script>";
  $string=$this->checkCode;
  for($i=0;$i<$this->codeNum;$i++) {
   $x=rand(1,4)+$this->width*$i/$this->codeNum;
   $y=rand(1,$this->height/4);
   $color=imagecolorallocate($this->image, rand(0,128), rand(0,128), rand(0,128));
   $fontSize=rand(4,5);
   imagestring($this->image, $fontSize, $x, $y, $string[$i], $color);
  } 
 }
 //输出图像
 private function outputImage() {
  if(imagetypes() & IMG_GIF) {
   header("Content-type:image/gif");
   imagepng($this->image);
  }else if(imagetypes() & IMG_JPG) {
   header("Content-type:image/jpeg");
   imagepng($this->image);
  }else if(imagetypes() & IMG_PNG) {
   header("Content-type:image/png");
   imagepng($this->image);
  }else if(imagetypes() & IMG_WBMP) {
   header("Content-type:image/vnd.wap.wbmp");
   imagepng($this->image);
  }else {
   die("PHP不支持图像创建");
  }
 }
 function __destruct() {
  imagedestroy($this->image);
 }
}
$code=new ValidationCode(60, 20, 4);
$_SESSION['checkCode']=$code->getCheckCode();     //将验证码的值存入session中以便在页面中调用验证
$code->showImage();   //输出验证码
?>

checkCode.php

和index.php结合以验证输入的正确性,并用Ajax改变前端显示

<?php
 session_start();
 //注意如此此处存在中文验证码时,用Ajax传值要注意存在中文乱码的问题
 $validateCode=$_POST['validateCode'];
 if(strtoupper($validateCode)==strtoupper($_SESSION['checkCode']))          //判断文本框中输入的值和$_SESSION中保存的验证码值是否相等
  echo "1";        
 else
  echo "0";
?>

原文来自:http://blog.csdn.net/fanteathy/article/details/7376890

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章