增加动态验证码,跳动的验证码增强视觉体验
首先打开Thinkphp官方的Image类文件,默认在ThinkPHP\Extend\Library\ORG\Util下面。
打开找到第405行下面添加(也就是生成图像验证码方法下面),增加一个生成动态验证码的方法。 /**<br>
* 生成动态图像验证码<br>
* @static<br>
* @access public<br>
* @param string $length 位数<br>
* @param string $mode 类型<br>
* @param string $width 宽度<br>
* @param string $height 高度<br>
* @return string<br>
*/<br>
static function buildActiveImageVerify($length=4, $mode=1, $width=60, $height=22, $verifyName='verify') {<br>
import('ORG.Util.String');<br>
import('ORG.Util.GIFEncoder');<br>
$randval = String::randString($length, $mode);<br>
session($verifyName, md5($randval));<br>
$width = ($length * 10 + 10) > $width ? $length * 10 + 10 : $width;<br>
// 生成一个32帧的GIF动画<br>
for($i=0;$i
ob_start();<br>
$image=imagecreate($width,$height);<br>
imagecolorallocate($image,0,0,0);<br>
// 设定文字颜色数组 <br>
$colorList[]=ImageColorAllocate($image,15,73,210);<br>
$colorList[]=ImageColorAllocate($image,0,64,0);<br>
$colorList[]=ImageColorAllocate($image,0,0,64);<br>
$colorList[]=ImageColorAllocate($image,0,128,128);<br>
$colorList[]=ImageColorAllocate($image,27,52,47);<br>
$colorList[]=ImageColorAllocate($image,51,0,102);<br>
$colorList[]=ImageColorAllocate($image,0,0,145);<br>
$colorList[]=ImageColorAllocate($image,0,0,113);<br>
$colorList[]=ImageColorAllocate($image,0,51,51);<br>
$colorList[]=ImageColorAllocate($image,158,180,35);<br>
$colorList[]=ImageColorAllocate($image,59,59,59);<br>
$colorList[]=ImageColorAllocate($image,0,0,0);<br>
$colorList[]=ImageColorAllocate($image,1,128,180);<br>
$colorList[]=ImageColorAllocate($image,0,153,51);<br>
$colorList[]=ImageColorAllocate($image,60,131,1);<br>
$colorList[]=ImageColorAllocate($image,0,0,0);<br>
$fontcolor=ImageColorAllocate($image,0,0,0);<br>
$gray=ImageColorAllocate($image,245,245,245);<br>
$color=imagecolorallocate($image,255,255,255);<br>
$color2=imagecolorallocate($image,255,0,0);<br>
imagefill($image,0,0,$gray);<br>
$space=15;// 字符间距<br>
if($i>0){// 屏蔽第一帧<br>
$top=0;<br>
for($k=0;$k
$colorRandom=mt_rand(0,sizeof($colorList)-1);<br>
$float_top=rand(0,4);<br>
$float_left=rand(0,3);<br>
imagestring($image,6,$space*$k,$top+$float_top,substr($randval,$k,1),$colorList[$colorRandom]);<br>
}<br>
}<br>
for($k=0;$k
$colorRandom=mt_rand(0,sizeof($colorList)-1);<br>
imagesetpixel($image,rand()%70,rand()%15,$colorList[$colorRandom]);<br>
<br>
}<br>
// 添加干扰线<br>
for($k=0;$k
$colorRandom=mt_rand(0,sizeof($colorList)-1);<br>
$todrawline=1;<br>
if($todrawline){<br>
imageline($image,mt_rand(0,$width),mt_rand(0,$height),mt_rand(0,$width),mt_rand(0,$height),$colorList[$colorRandom]);<br>
}else{<br>
$w=mt_rand(0,$width);<br>
$h=mt_rand(0,$width);<br>
imagearc($image,$width-floor($w / 2),floor($h / 2),$w,$h, rand(90,180),rand(180,270),$colorList[$colorRandom]);<br>
}<br>
}<br>
imagegif($image);<br>
imagedestroy($image);<br>
$imagedata[]=ob_get_contents();<br>
ob_clean();<br>
++$i;<br>
}<br>
$gif=new GIFEncoder($imagedata);<br>
Header('Content-type:image/gif');<br>
echo $gif->GetAnimation();<br>
}
然后将GIFEncoder类文件放入同级目录中<?php <br />
/**<br>
*GIFEncoder类<br>
**/<br>
Class GIFEncoder{<br>
var $GIF="GIF89a"; /* GIF header 6 bytes */ <br>
var $VER="GIFEncoder V2.06"; /* Encoder version */ <br>
var $BUF=Array();<br>
var $LOP=0;<br>
var $DIS=2;<br>
var $COL=-1;<br>
var $IMG=-1;<br>
var $ERR=Array(<br>
'ERR00'=>"Does not supported function for only one image!", <br>
'ERR01'=>"Source is not a GIF image!", <br>
'ERR02'=>"Unintelligible flag ", <br>
'ERR03'=>"Could not make animation from animated GIF source", <br>
);<br>
function GIFEncoder($GIF_src,$GIF_dly=100,$GIF_lop=0,$GIF_dis=0, $GIF_red=0,$GIF_grn=0,$GIF_blu=0,$GIF_mod='bin'){<br>
if(!is_array($GIF_src)&&!is_array($GIF_tim)){<br>
printf("%s: %s",$this->VER,$this->ERR['ERR00']);<br>
exit(0);<br>
} <br>
$this->LOP=($GIF_lop>-1)?$GIF_lop:0;<br>
$this->DIS=($GIF_dis>-1)?(($GIF_dis
$this->COL=($GIF_red>-1&&$GIF_grn>-1&&$GIF_blu>-1)?($GIF_red |($GIF_grn
<br>
for($i=0,$src_count=count($GIF_src);$i
if(strToLower($GIF_mod)=="url"){<br>
$this->BUF[]=fread(fopen($GIF_src [$i],"rb"),filesize($GIF_src [$i]));<br>
}elseif(strToLower($GIF_mod)=="bin"){<br>
$this->BUF [ ]=$GIF_src [ $i ];<br>
}else{<br>
printf("%s: %s(%s)!",$this->VER,$this->ERR [ 'ERR02' ],$GIF_mod);<br>
exit(0);<br>
} <br>
if(substr($this->BUF[$i],0,6)!="GIF87a"&&substr($this->BUF [$i],0,6)!="GIF89a"){<br>
printf("%s: %d %s",$this->VER,$i,$this->ERR ['ERR01']);<br>
exit(0);<br>
} <br>
for($j=(13+3*(2BUF[$i]{10})&0x07))),$k=TRUE;$k;$j++){<br>
switch($this->BUF [$i]{$j}){<br>
case "!": <br>
if((substr($this->BUF[$i],($j+3),8))=="NETSCAPE"){<br>
printf("%s: %s(%s source)!",$this->VER,$this->ERR ['ERR03'],($i+1));<br>
exit(0);<br>
} <br>
break;<br>
case ";": <br>
$k=FALSE;<br>
break;<br>
} <br>
} <br>
} <br>
GIFEncoder::GIFAddHeader();<br>
for($i=0,$count_buf=count($this->BUF);$i
GIFEncoder::GIFAddFrames($i,$GIF_dly[$i]);<br>
} <br>
GIFEncoder::GIFAddFooter();<br>
} <br>
function GIFAddHeader(){<br>
$cmap=0;<br>
if(ord($this->BUF[0]{10})&0x80){<br>
$cmap=3*(2BUF [0]{10})&0x07));<br>
$this->GIF.=substr($this->BUF [0],6,7);<br>
$this->GIF.=substr($this->BUF [0],13,$cmap);<br>
$this->GIF.="!\377\13NETSCAPE2.0\3\1".GIFEncoder::GIFWord($this->LOP)."\0";<br>
} <br>
} <br>
function GIFAddFrames($i,$d){<br>
$Locals_str=13+3*(2 BUF[$i]{10})&0x07));<br>
$Locals_end=strlen($this->BUF[$i])-$Locals_str-1;<br>
$Locals_tmp=substr($this->BUF[$i],$Locals_str,$Locals_end);<br>
$Global_len=2BUF [0]{10})&0x07);<br>
$Locals_len=2BUF[$i]{10})&0x07);<br>
$Global_rgb=substr($this->BUF[0],13,3*(2BUF[0]{10})&0x07)));<br>
$Locals_rgb=substr($this->BUF[$i],13,3*(2BUF[$i]{10})&0x07)));<br>
$Locals_ext="!\xF9\x04".chr(($this->DIS>0)&0xFF).chr(($d>>8)&0xFF)."\x0\x0";<br>
if($this->COL>-1&&ord($this->BUF[$i]{10})&0x80){<br>
for($j=0;$jBUF[$i]{10})&0x07));$j++){<br>
if(ord($Locals_rgb{3*$j+0})==($this->COL>> 0)&0xFF&&ord($Locals_rgb{3*$j+1})==($this->COL>> 8)&0xFF&&ord($Locals_rgb{3*$j+2})==($this->COL>>16)&0xFF){<br>
$Locals_ext="!\xF9\x04".chr(($this->DIS>0)&0xFF).chr(($d>>8)&0xFF).chr($j)."\x0";<br>
break;<br>
} <br>
} <br>
} <br>
switch($Locals_tmp{0}){<br>
case "!": <br>
$Locals_img=substr($Locals_tmp,8,10);<br>
$Locals_tmp=substr($Locals_tmp,18,strlen($Locals_tmp)-18);<br>
break;<br>
case ",": <br>
$Locals_img=substr($Locals_tmp,0,10);<br>
$Locals_tmp=substr($Locals_tmp,10,strlen($Locals_tmp)-10);<br>
break;<br>
} <br>
if(ord($this->BUF[$i]{10})&0x80&&$this->IMG>-1){<br>
if($Global_len==$Locals_len){<br>
if(GIFEncoder::GIFBlockCompare($Global_rgb,$Locals_rgb,$Global_len)){<br>
$this->GIF.=($Locals_ext.$Locals_img.$Locals_tmp);<br>
}else{<br>
$byte=ord($Locals_img{9});<br>
$byte|=0x80;<br>
$byte&=0xF8;<br>
$byte|=(ord($this->BUF [0]{10})&0x07);<br>
$Locals_img{9}=chr($byte);<br>
$this->GIF.=($Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp);<br>
} <br>
}else{<br>
$byte=ord($Locals_img{9});<br>
$byte|=0x80;<br>
$byte&=0xF8;<br>
$byte|=(ord($this->BUF[$i]{10})&0x07);<br>
$Locals_img {9}=chr($byte);<br>
$this->GIF.=($Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp);<br>
} <br>
}else{<br>
$this->GIF.=($Locals_ext.$Locals_img.$Locals_tmp);<br>
} <br>
$this->IMG=1;<br>
} <br>
function GIFAddFooter(){<br>
$this->GIF.=";";<br>
} <br>
function GIFBlockCompare($GlobalBlock,$LocalBlock,$Len){<br>
for($i=0;$i
if($GlobalBlock{3*$i+0}!=$LocalBlock{3*$i+0}||$GlobalBlock{3*$i+1}!=$LocalBlock{3*$i+1}||$GlobalBlock{3*$i+2}!=$LocalBlock{3*$i+2}){<br>
return(0);<br>
} <br>
} <br>
return(1);<br>
} <br>
function GIFWord($int){<br>
return(chr($int&0xFF).chr(($int>>8)&0xFF));<br>
} <br>
function GetAnimation(){<br>
return($this->GIF);<br>
} <br>
}
具体使用方法和原来基本一致,只是不要传type参数,因为默认动态必须是gif格式,另外图片宽度不能小于60。 /**<br>
* 生成验证码<br>
* @access public<br>
* @return void<br>
*/ <br>
public function verify(){<br>
import("ORG.Util.Image");<br>
Image::buildActiveImageVerify(4,1);<br>
}
AD:真正免费,域名+虚机+企业邮箱=0元