`
阅读更多

最近查一个“验证码不显示”的问题,解决的过程中学到了一些东西,这里做个记录。先贴两个验证码的代码吧。

第一个:

<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
//验证码
error_reporting(E_ERROR | E_WARNING | E_PARSE);
$verify=new verifyCode;

for($i=0;$i<=3;$i++){
	$zz=rand(1,9);
	$code.=$zz;
}
setCookie("CODEIMG",md5($code),time()+360000,"/");

$verify->vCode($code);
$code = $verify->Output();
class verifyCode{
	var $Noisy = 5; // 干扰点出现的概率
	var $Count = 4; // 字符数量
	var $Width = 60; // 图片宽度
	var $Height = 18; // 图片高度
	var $Angle = 5; // 角度随机变化量
	var $Offset = 3; // 偏移随机变化量
	var $Border = 2; // 边框大小
	var $imgData = "";
	var $Graph=array();
	var $code = "";

function vCode($code){
	global $code;
	$this->code = $code;
	for($i=0;$i<strlen($code);$i++){
		$this->SetDraw(substr($code,$i,1), $i);
	}
        
}
        
function SetDot($pX, $pY){
	if($pX * ($this->Width-$pX-1) >= 0 && $pY * ($this->Height-$pY-1) >= 0){
		$this->Graph[$pX][$pY] = 1;
	}
}

function Rnd(){
	mt_srand((double)microtime() * 1000000);
	return mt_rand(1, 999)/1000;
}

function Sgn($v){
   if($v>0) return 1;
   if($v==0) return 0;
   if($v<0) return -1;
}

function SetDraw($pIndex, $pNumber){
	// 字符数据
	$DotData[0] = array(10, 1, 80, 1, 80, 100,10,100,10,1);
	$DotData[1] = array(30, 15, 50, 1, 50, 100);
	$DotData[2] = array(1 ,34 ,30 ,1 ,71, 1, 100, 34, 1, 100, 93, 100, 100, 86);
	$DotData[3] = array(1, 1, 100, 1, 42, 42, 100, 70, 50, 100, 1, 70);
	$DotData[4] = array(100, 73, 6, 73, 75, 6, 75, 100);
	$DotData[5] = array(100, 1, 1, 1, 1, 50, 50, 35, 100, 55, 100, 80, 50, 100, 1, 95);
	$DotData[6] = array(100, 20, 70, 1, 20, 1, 1, 30, 1, 80, 30, 100, 70, 100, 100, 80, 100, 60, 70, 50, 30, 50, 1, 60);
	$DotData[7] = array(6, 26, 6, 6, 100, 6, 53, 100);
	$DotData[8] = array(100, 30, 100, 20, 70, 1, 30, 1, 1, 20, 1, 30, 100, 70, 100, 80, 70, 100, 30, 100, 1, 80, 1, 70, 100, 30);
	$DotData[9] = array(1, 80, 30, 100, 80, 100, 100, 70, 100, 20, 70, 1, 30, 1, 1, 20, 1, 40, 30, 50, 70, 50, 100, 40);
	
	$vExtent = $this->Width / strlen($this->code);
	$Margin[0] = $this->Border +$vExtent *$pNumber+ $vExtent * ($this->Rnd() * $this->Offset) / 100;
	$Margin[1] = $vExtent * ($pNumber + 1) - $this->Border - $vExtent * ($this->Rnd() * $this->Offset) / 100;
	$Margin[2] = $this->Border + $this->Height * ($this->Rnd() * $this->Offset) / 100;
	$Margin[3] = $this->Height - $this->Border - $this->Height * ($this->Rnd() * $this->Offset) / 100;
	
	$vWidth = intval($Margin[1] - $Margin[0]);
	
	$vHeight = intval($Margin[3] - $Margin[2]);
	
	//起始坐标
	$vStartX = intval(($DotData[$pIndex][0]-1) * $vWidth / 100);
	
	$vStartY = intval(($DotData[$pIndex][1]-1) * $vHeight / 100);
	
	for ($i = 1 ;$i<=count($DotData[$pIndex])/2;$i++){
		If($DotData[$pIndex][2*$i-2] <> 0 && $DotData[$pIndex][2*$i] <> 0){
			// 终点坐标
			$vEndX = ($DotData[$pIndex][2*$i]-1) * $vWidth / 100;
			
			$vEndY = ($DotData[$pIndex][2*$i+1]-1) * $vHeight / 100;
			
			// 横向差距
			$vDX = $vEndX - $vStartX;
			// 纵向差距
			$vDY = $vEndY - $vStartY;
			
			// 倾斜角度
			if($vDX == 0)
					$vAngle = $this->Sgn($vDY) * 3.14/2;
			else
					$vAngle = atan($vDY /$vDX);
			
			//两坐标距离
			if(sin($vAngle) == 0)
					$vLength = $vDX;
			else
					$vLength = $vDY / sin($vAngle);
			
			// 随机转动角度
			$vAngle = $vAngle + ($this->Rnd() - 0.5) * 2 * $this->Angle * 3.14 * 2 / 100;
			
			$vDX = intval(cos($vAngle) * $vLength);
			
			$vDY = intval(sin($vAngle) * $vLength);
			
			if(abs($vDX) > abs($vDY))
					$vDeltaT = abs($vDX) ;
			else
					$vDeltaT = abs($vDY);
			
			for($j = 1;$j<=$vDeltaT;$j++)
					$this->SetDot($Margin[0] + $vStartX + $j * $vDX / $vDeltaT, $Margin[2] + $vStartY + $j * $vDY / $vDeltaT);
			
			
			$vStartX = $vStartX + $vDX;
			
			$vStartY = $vStartY + $vDY;
	}
	}
}
        
function Output(){
	$out = "";
	
	// 文件类型
	$out .= "GIF";
	// 版本信息
	$out .= "89a";
	// 逻辑屏幕宽度
	$out .= chr($this->Width % 256).chr(($this->Width/256) % 256);
	// 逻辑屏幕高度
	$out .= chr($this->Height % 256).chr(($this->Height / 256) % 256);
	
	$out .= chr(128) . chr(0) . chr(0);
	// 全局颜色列表
	$out .= chr(0xEE).chr(0xEE).chr(0xEE);
	$out .= chr(0x00).chr(0x00).chr(0x00);
	
	// 图象标识符
	$out .= ",";
	
	$out .= chr(0).chr(0).chr(0).chr(0);
	// 图象宽度
	$out .= chr($this->Width % 256).chr(($this->Width/256) % 256);
	// 图象高度
	$out .= chr($this->Height % 256).chr(($this->Height / 256) % 256);
	$out .= chr(0).chr(7).chr(255);
					
	for($y = 0;$y<$this->Height;$y++)
	{
			for($x = 0;$x<$this->Width;$x++)
			{
					if($this->Rnd() < $this->Noisy / 100)
							$out .= chr(1-$this->Graph[$x][$y]);
					else
					{
							if($x * ($x-$this->Width) == 0 || $y * ($y-$this->Height) == 0)
									$out .= chr($this->Graph[$x][$y]);
							else
							{
									if($this->Graph[$x-1][$y]== 1 || $this->Graph[$x][$y] || $this->Graph[$x][$y-1] == 1)
											$out .= chr(1);
									else
											$out .= chr(0);
							}
					}
					if(($y * $this->Width + $x + 1) % 126 == 0)
					{
							$out .= chr(128);
							$i++;
					}
					if(($y * $this->Width + $x + $i + 1) % 255 == 0)
					{
							if(($this->Width*$this->Height - $y * $this->Width - $x - 1) > 255)
									$out .= chr(255);
							else
									$out .= chr($this->Width * $this->Height %255);
					}
			}
	}
	$out .= chr(128).chr(0).chr(129).chr(0).chr(59);
	ob_clean();
	header("Expires: -9999");
	header("Pragma: no-cache");
	header("cache-ctrol: no-cache");
	header("Content-Type:image/gif");
	echo $out;
}
}
?>

这个文件直接引入到img的src下就能用,大小是:60*18。

遇到的问题是:验证码图片不显示,也不报错,最后的解决是在Output()方法中添加了ob_clean()。

 

第二个:

这个是在网上看到的,转载链接如下:http://blog.csdn.net/tenghu8888/article/details/39499925

vcode.class.php:

<?php  
/**  
*验证码类  
*/  
class Vcode{  
private $width;//图片宽度  
private $height;//图片高度  
private $num;//验证码个数  
private $img;//图片资源  
private $code;//验证码  
private $pointNum;//干扰点个数  
private $lineNum;//干扰线个数  
private $fontFile;//字体文件  
  
//构造函数初始化相关数据  
function __construct($width=85,$height=34,$num=4){  
    $this->width=$width;  
    $this->height=$height;  
    $this->num=$num;  
    $this->code=$this->createCode();  
    $this->pointNum=100;  
    $this->lineNum=10;  
    $this->fontFile="STLITI.TTF";  
}  
  
/**  
  *用于设置成员属性  
  *@param string $key 成员属性名  
  *@param mixed $value 成员属性值  
  *@return object 返回自己对象$this,可用于连贯操作  
  */  
public function set($key,$val){  
    //get_class_vars() 获取类中的属性组成的数组  
    //get_class() 返回对象的类名  
    if(array_key_exists($key,get_class_vars(get_class($this)))){  
	$this->setOption($key,$val);  
    }  
    return $this;  
}  
//设置参数  
private function setOption($key,$value){  
    $this->$key=$value;  
}  
  
//获取验证码  
public function getCode(){  
    return $this->code;  
}  
  
//输出图像  
public function outImg(){  
    //创建图像  
    $this->createImage();  
    //画验证码  
    $this->drawCode();  
    //画干扰元素  
    $this->drawDisturbColor();  
    //输出图像  
    $this->printImg();  
}  
  
//画验证码  
private function drawCode(){  
    $this->fontFile="./font/".$this->fontFile;  
    for($i=0;$i<$this->num;$i++){  
	//设置随机颜色  
	$randColor=imagecolorallocate($this->img,rand(0,128),rand(0,128),rand(0,128));  
	//字体大小  
	$fontSize=rand(20,23);  
	//字体水平位置  
	$x=($this->width/$this->num)*$i;  
	//水平方向的位置  
	$y=rand($fontSize,imagefontheight($fontSize)+3);  
	//画字体  
	imagettftext($this->img,$fontSize,0,$x,$y,$randColor,$this->fontFile,$this->code{$i});  
    }  
}  
//画干扰元素  
private function drawDisturbColor(){  
    //画干扰点  
    for($i=0;$i<$this->pointNum;$i++){  
	//设置随机颜色  
	$randColor=imagecolorallocate($this->img,rand(0,255),rand(0,255),rand(0,255));  
	//画点  
	imagesetpixel($this->img,rand(1,$this->width-2),rand(1,$this->height-2),$randColor);  
    }  
      
    //画干扰线  
    for($i=0;$i<$this->lineNum;$i++){  
	//设置随机颜色  
	$randColor=imagecolorallocate($this->img,rand(0,200),rand(0,200),rand(0,200));  
	//画线  
	imageline($this->img,rand(1,$this->width-2),rand(1,$this->height-2),rand(1,$this->height-2),rand(1,$this->width-2),$randColor);  
    }  
}  
  
//创建图像  
private function createImage(){  
    //创建一个真彩色图像  
    $this->img=imagecreatetruecolor($this->width,$this->height);  
    //设置背景色  
    $bgColor=imagecolorallocate($this->img,rand(200,255),rand(200,255),rand(200,255));  
    //填充背景色  
    imagefill($this->img,0,0,$bgColor);  
    //设置边框颜色  
    $borderColor=imagecolorallocate($this->img,0,0,0);  
    //画一个边框  
    imagerectangle($this->img,0,0,$this->width-1,$this->height-1,$borderColor);  
}  
  
//输出图像  
private function printImg(){ 
	ob_clean();
    if(imagetypes() & IMG_PNG){  
	//针对png	
	header("Content-Type:image/png");  
	imagepng($this->img);  
    }else if(imagetypes() & IMG_JPG){  
	//针对jpg  
	header("Content-Type:image/jpeg");  
	imagejpeg($this->img,null,100);  
    }else if(imagetypes() & IMG_GIF){  
	//针对Gif  
	header("Content-Type:image/gif");  
	imagegif($this->img);  
    }else if(imagetypes() & IMG_WBMP){  
	// 针对 WBMP  
	header('Content-Type: image/vnd.wap.wbmp');  
	imagewbmp($this->img);  
    }else{  
	die('No image support in this PHP server');  
    }  
}  
  
//创建验证码  
private function createCode(){  
    //默认字符串  
    $codes="123456789abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXY";  
    //生成验证码  
    $code="";  
    for($i=0;$i<$this->num;$i++){  
	$code.=$codes{rand(0,strlen($codes)-1)};  
    }  
    return $code;  
}  
  
//析构函数用于销毁图像资源  
function __destruct(){  
    imagedestroy($this->img);  
}  
}

 请求信息如下(image_002.php):

<?php  
    //开启Session  
    session_start();  
    //引入验证码类  
    include("vcode.class.php");  
    //创建验证码类  
    $vcode=new Vcode();  
    //将获取的验证码存入到session中  
    $_SESSION['code']=$vcode->getCode();  
    //$vcode->set("pointNum",10);//自定义干扰点个数  
    //$vcode->set("lineNum",10);//自定义干扰线个数  
    //$vcode->set("fontFile","wawa.ttf");//自定义字体文件  
    //输出图像  
    $vcode->outImg(); 
?>

页面上只用img标签直接调用就好:

<img src="image_002.php" onclick="this.src='image_002.php?Math.random()'"/> 

 

使用这个验证码时遇到了一个问题:图片因存在错误而无法显示

主要通过两步解决了:

第一步:

原因:vcode.class.php中imagettftext调用font生成验证码时找不到字体导致出错。

解决办法:很简单,在项目里新建一个font(drawCode方法中指定的目录为font),将指定的字体SIMYOU.TTF从Windows下拷贝过来,就能解决这个问题

 

第二步:在printImg()函数的第一行添加一句ob_clean()。

以上两步之后,验证码就出来了。

 

上面贴的第一个验证码显示不出来就是因为没有添加ob_clean(),这个问题是在解决第二个验证码的问题时顺带解决的,所以讲其粘在第一了。

分享到:
评论

相关推荐

    PHP简单验证码的实现

    本项目以"PHP简单验证码的实现"为主题,旨在帮助初学者理解并掌握如何在PHP中创建一个基本的验证码功能。 验证码的核心在于生成随机且难以被机器识别的图像,通常包含字母、数字的组合,有时会添加扭曲、噪点等元素...

    PHP登录验证码功能

    PHP登录验证码功能PHP写的登录验证码功能

    PHP编写登录验证码功能 附调用方法

    PHP验证码功能的实现主要依赖于几个关键点:生成随机字符串、创建图像、设置Cookie或Session以及使用GD库进行图像处理。 首先,生成随机字符串通常会使用一个自定义函数,比如文中提到的`domake_password`函数。这...

    好用的php验证码类库.zip

    总的来说,"好用的php验证码类库"为PHP开发者提供了一种便捷的方式,帮助他们在项目中快速实现高效且安全的验证码功能。通过深入理解和合理使用,可以大大提高开发效率,同时保障网站的安全性。

    php验证码类 php中文验证码

    在PHP中,创建自定义的验证码类可以帮助开发者实现更安全、更个性化的验证功能。这里我们将深入探讨“php中文验证码类”的相关知识点。 首先,验证码通常由随机字符组成,包括字母、数字甚至中文字符,目的是增加...

    PHP语音验证码和PHP图片验证码

    本资源提供了PHP实现的语音验证码和图片验证码的完整方案,适用于网站登录验证和投票功能。 首先,让我们详细了解PHP图片验证码(CAPTCHA)的工作原理和实现。图片验证码通常由一串随机生成的字母或数字组成,这些...

    php验证码简单源码

    本篇文章将深入探讨这个"php验证码简单源码"的知识点。 首先,验证码的基本原理是生成一段随机的字符串或数字,然后通过图像或其他形式显示给用户,用户在提交表单时需要输入看到的验证码。这个过程要求验证码在...

    php源码 验证码 类

    验证码在Web开发中扮演着重要的角色,主要用于防止自动机器人、恶意攻击或垃圾信息的提交。...本篇文章将深入探讨PHP验证码类的...开发者在编写此类时,需要综合考虑安全性、效率和易用性,确保验证码功能的可靠和实用。

    漂亮的php 验证码

    在HTML页面中,通常会有一个图像标签 `&lt;img&gt;`,它的 `src` 属性指向PHP验证码生成脚本(如 `code.php`),这样当用户加载页面时,服务器会动态生成一个验证码图片并显示在浏览器上。此外,HTML页面还会包含一个表单...

    PHP发送邮箱验证码

    本教程将深入讲解如何使用PHP来发送QQ邮箱的验证码。 首先,要实现PHP发送邮箱验证码,我们需要了解SMTP(Simple Mail Transfer Protocol)协议。SMTP是互联网上传输电子邮件的标准,大多数邮件服务提供商,包括QQ...

    PHP随机验证码含有5种样式

    在PHP中实现验证码功能,可以有效地增加网站的安全性。本篇文章将深入探讨PHP实现的五种不同类型的验证码,包括中文、英文以及数字验证码。 首先,我们来了解一下验证码的基本原理。验证码通常由一串随机生成的字符...

    PHP验证码封装类

    在这个“PHP验证码封装类”中,开发者已经创建了一个易于使用且功能完善的验证码生成器,它可以帮助我们快速地在项目中集成验证码功能。 验证码类通常包括以下几个关键部分: 1. **随机字符串生成**:验证码通常由...

    PHP实现的验证码类库

    通过这个PHP验证码类库,开发者可以快速集成验证码功能,提升网站的安全性,同时也能深入理解PHP的图像处理和session管理等核心概念。在实际应用中,可以根据具体需求对类库进行扩展和定制,以达到最佳的用户体验和...

    简单完整的PHP验证码

    在PHP中实现验证码功能,可以帮助防止自动机器人和恶意脚本对网站进行自动化操作,如注册、登录或提交表单。下面,我们将深入探讨如何在PHP中创建一个简单而完整的数字与英文混合的验证码系统。 1. **验证码的基本...

    PHP验证码代码,可参考

    这两个文件很可能是实现验证码功能的核心部分。下面将分别解释它们可能的作用,并探讨PHP验证码的实现原理。 `www.php` 文件可能是验证码的前端展示部分,它负责在网页上显示验证码图像。通常,这个文件会通过以下...

    php验证码文件类.zip

    "php验证码文件类.php"是实现验证码功能的PHP源代码文件,而"php中文网免费下载站.txt"和"php中文网下载站.url"可能是提供该类库的来源信息,方便用户查找更多相关资源或学习材料。对于初学者,阅读并理解这个类的源...

    PHP简单验证码功能机制实例详解

    PHP简单验证码功能机制的核心目的在于保护网站免受自动化攻击,如自动化的恶意注册、登录或表单提交等。验证码的原理基于人类与机器在识别图像上的差异,通过生成一个只有人类能够识别的字符序列,确保请求来自真实...

    Php各种验证码实现

    这篇内容将详细介绍PHP如何实现各种验证码功能。 一、基础原理 验证码的核心在于生成一组随机数据并将其与服务器端保持同步,同时在客户端展示。在PHP中,我们可以通过GD库或Imagick扩展来创建图像,生成随机文本并...

    PHP验证码小实例

    本实例将深入讲解如何使用PHP实现一个简单的验证码功能。 首先,验证码的基本原理是生成一段随机的字符串,将其显示在图像上,并将其值存储在一个会话(session)中。当用户提交表单时,服务器会检查输入的验证码...

Global site tag (gtag.js) - Google Analytics