php实现验证码
网站:http://php.net/manual/zh/book.image.php
验证码为全自动区分计算机和人类的图灵测试时的缩写,是一种区分用户是计算机和人的公共全自动程序。
学习的目的:屏蔽机器的请求,保障业务不受机器提交请求干扰
为什么要屏蔽机器请求:一般服务端业务,写请求产生的消耗要远远大于读请求,
步骤:
1、生成底图;
2、生成验证内容;
3、生成验证码图片;
4、校验验证内容;
技术点:
a:底图的实现,并且添加干扰元素
php图片处理库GD,http://php.net.gd;
b:生成验证的内容
简单的随机数生成:mt_rand;
随机数字+字母生成,需要ASCII码理论基础;
随机中文内容的生成,需要UTF-8编码理论基础;
c:验证内容保存在服务器
需要php操作SESSION操作;
d:验证内容的验证
需要有前段AJAX基础;
开发前的准备:
1:php运行环境
2:检查php是否支持GD
LNMP.org : linux系统下
XAMPP\WampServer :windows 系统下
(webServer php)
检验方法:
新建一个php文件
<?php
phpinfo();
?>
一:实现简单的验证码 ;实现验证码的底图
<?php
$image =imagecreatetruecolor(100 , 30);//创建画布,默认输出的是一个黑色的背景
$bgcolor=imagecolorallocate($image,255,255,255); //设置色彩
imagefill($image,0,0,$bgcolor); //填充画布
<随机数代码>
<点干扰元素>
<线干扰元素>
header('content-type:image/png'); //输出header信息,
imagepng($image);//以png格式将图像输出到浏览器或者文件
imagedestroy();//销毁一图像
?>
二:实现简单的验证码:验证码
for($i=0 ; $i<4 ; $i++){
$fontsize=6;
$fontcolor =imagecolorallocate($image,rand(0,100),rand(0,100),rand(0,100));
$fontcontent=rand(0,9);
$x=($i*100/4)+rand(5,10);
$y=rand(5,10);
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
// fontcolor颜色将字符串 fontcontent画到 image 所代表的图像的 x,y 坐标处(这是字符串左上角坐标,整幅图像的左上角为 0,0)
}
//字母数字混合的验证码
for($i=0;$i<4;$i++){
$fontsize=6;
$fontcolor=imagecolorallocate($image,rand(1,120),rand(1,120),rand(1,120));
$data='12ab34cd56ef7gh8ij9klm0nop';
$fontcontent=substr($data,rand(0,strlen($data)-1),1);
$x=($i*100/4)+rand(5,10);
$y=rand(5,10);
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
三:实现简单的验证码:干扰元素
//增加干扰元素:点
for($i=0;$i<200;$i++){ $pointercolor=imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
imagesetpixel($image,rand(1,99),rand(1,29),$pointercolor);
}
//增加线干扰元素
for($i=0;$i<6;$i++){ $linecolor=imagecolorallocate($image,rand(100,200),rand(100,200),rand(100,200));
imageline($image,rand(0,100),rand(0,30),rand(0,100),rand(0,30),$linecolor);
}
四:通过SESSION存储验证信息
在服务端记录验证码信息,便于用户输入后做校验
1:session_start();//位于代码的开头部分
2:定义一个变量$captch_code='';
$captch_code.=$fontcontent;
$_SESSION['变量名']=$captch_code;
a>在多服务器的情况下,我们需要考虑集中管理session信息
五:实现简单的验证码:验证码通过表单提交、验证
将已经生成的验证码提供给用户,并验证用户验证码的正确性
<?php
if(isset($_REQUEST['authcode'])){
session_start();
if($_REQUEST['authcode']==$_SESSION['authcode']){
echo '<font color="#0000CC">输入正确</font>';
}else{
echo '<font color="#CC0000"><b>输入错误</b></font>';
}
exit();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<title>验证码验证</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<script type="text/javascript">
</script>
<style type="text/css">
</style>
</head>
<body>
<form method="post" action="./form.php">
<p>验证图片:<img border="1" src="./captcha.php?r=<?php echo rand();?>"> </p>
<p>请输入验证码的内容:<input type="text" name="authcode" value=""/></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
六:如何让验证码动态校验
看不清、换一个的实现原理
1:增加一个可点击的“换一个”的文案
2:用js选择器选取验证码图片
3:用js修改验证码图片地址(改src)
思想:设置一个单击事件:获取img的src并改变其值
<img id="captcha_img" src="./captcha.php?r=<?php echo rand();?>">
<a href="javascript:void(0)" onclick="document.getElementById('captcha_img').src='./captcha.php?r='+Math.random()">换一个?</a>
七:图片验证码:
1:准备一定量的验证码物料库
2:做好物料的对应关系
<?php
session_start();
$table=array(
'pic0'=>'狗',
'pic1'=>'猫',
‘pic2’=>'鱼',
‘pic3’=>'鸟',
);
$index=rand(0,3);
$value=$table['pic'.$index];
$_SESSION['authcode']=$value;
$filename=dirname(__FILE__).'\\pic'.$index.'.jpg';
$contents=file_get_contents($filename);
header('content-type:images/jsp');
echo $contents;
可以得到验证图片信息
<p>验证图片:<img id="captcha_img" border="1" src="./captcha.img.php?r=<?php echo rand();?>" width="200" height="200">
<a href="javascript:void(0)" onclick="document.getElementById('captcha_img').src='./captcha.php?r='+Math.random()">换一个?</a>
</p>
?>
八:汉字验证码:
依赖GD库的imagettftext()方法,
注意:
1:GBK编码时,需要将中文通过iconv()转为utf-8
header('content-type:text/html;charset=utf-8');
2:选用的ttf文件需要支持中文:字体格式为支持中文的
<?php
session_start();
$image=imagecreatetruecolor(200,60);
$bgcolor=imagecolorallocate($image,255,255,255);
imagefill($image,0,0,$bgcolor);
$fontface="simhei.ttf";
$strdb=array('慕','课','网','阿');
header('content-type:text/html;charset=utf-8');
$captch_code='';
for($i=0;$i<4;$i++){
$fontcolor=imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));
$cn=$strdb[$i];
$captch_code.=$cn;
imagettftext($image,mt_rand(20,24),mt_rand(20,60),(40*$i+20),mt_rand(30,35),$fontcolor, $fontface,$cn);
}
$_SESSION['authcode']=$captch_code;
?>
增加了字体格式、以及汉字集合的效果:
<?php
session_start();
$image=imagecreatetruecolor(200,60);
$bgcolor=imagecolorallocate($image,255,255,255);
imagefill($image,0,0,$bgcolor);
$font=array('simhei.ttf','simsun.ttc','STXIHEI.TTF','STXINWEI.TTF');
$str="信息科技时代偏爱汉字不知您是否了解模糊数学模糊控制或神经网络等新学科领域如果接触过您便会理解人类的艺术哲学感觉看似不精确但实为目前它们超越了当今人类的知识水平所能精确描述的范围随着人类认识能力的提高它们逐渐会被人类以全新的知识结构所精确地把握以上所举的新学科只是这一新知识结构序幕的小插曲汉字集中体现了东方艺术哲学是中华民族的文化底蕴之所在限于目前的科技水平它的智慧我们尚不能完全认识对它的发掘方兴未艾这种说法不是没有根据的的毕竟年前也没有人意识到传统汉字出版业要被淘汰年前的人没有料到汉字的输入会比英文快而且还会更快年前的人没有想到传统的报业媒体会被逐渐淘汰";
$strdb=str_split($str,3);//每三个字符切割成数组,因为中文在utf-8中每三个为一个汉字
header('content-type:text/html;charset=utf-8');
$captch_code='';
for($i=0;$i<4;$i++){
$fontcolor=imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));
//计算数组中的单元数目或对象中的属性个数
$cn=$strdb[rand(0,count($strdb))];
$captch_code.=$cn;
$fontface=$font[rand(0,count($font)-1)];
imagettftext($image,mt_rand(20,24),mt_rand(20,60),(40*$i+20),mt_rand(30,35),$fontcolor, $fontface,$cn);
}
$_SESSION['authcode']=$captch_code;
//增加干扰元素:点
for($i=0;$i<200;$i++){
$pointercolor=imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
imagesetpixel($image,rand(1,199),rand(1,59),$pointercolor);
}
//增加线干扰元素
for($i=0;$i<3;$i++){
$linecolor=imagecolorallocate($image,rand(100,200),rand(100,200),rand(100,200));
imageline($image,rand(0,200),rand(0,60),rand(0,200),rand(0,60),$linecolor);
}
header('content-type:image/png');
imagepng($image);
//end
imagedestroy();
?>