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

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