以前输出验证码的时候用过一个方法,在前台用JS生成验证码字符串,再传递到后台用PHP输出验证码图像。这样在验证时就不需要使用$_SESSION传递验证码的值,直接用JS比较生成的字符串和输入的字符串是否相等即可。
ValidationCode.class.php
但是这种方法的缺点是结构化编程比较明显,并且感觉脱节比较严重。在网上找了一些生成验证码的方法,也都不太完整,有些只包括生成图像并没有包括完整的验证部分,因此在此给出完整的验证码生成类和验证过程。
index.php
其中<img src="ValidationCode.class.php" id="checkImg">用于输出验证码图像。onClick= "this.src=this.src+'?' + 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";
- ?>