全面解析PHP验证码的实现原理 附php验证码小案例


Posted in PHP onAugust 17, 2016

拓展

我们需要开启gd拓展,可以使用下面的代码来查看是否开启gd拓展。

<?php

echo "Hello World!!!!";

echo phpinfo();
?>

然后在浏览器上Ctrl+F查找gd选项即可验证自己有没有装这个拓展,如果没有的话,还需要自己全装一下这个拓展。

背景图

imagecreatetruecolor

默认生成黑色背景

<?php
// 使用gd的imagecreatetruecolor();创建一张背景图
$image = imagecreatetruecolor(100,30);
// 在显示这张图片的时候一定要先声明头信息
header('content-type:image/png');

imagepng($image);

// 释放资源,销毁执行对象
imagedestroy($image);

imagecolorallocate

创建一个填充色,并用imagefill(image,x,y,color)方法来附着。

<?php
// 使用gd的imagecreatetruecolor();创建一张背景图
$image = imagecreatetruecolor(100,30);

// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 将填充色填充到背景图上
imagefill($image,0,0,$bgcolor);
// 在显示这张图片的时候一定要先声明头信息
header('content-type:image/png');

imagepng($image);

// 释放资源,销毁执行对象
imagedestroy($image);

imagepng

在使用这个方法之前,一定要先设置头信息,否则不会正常的显示图片 

imagedestory(image)

适时的释放资源会减轻对服务器请求的压力。 

简易数字验证码

imagecolorallocate

生成颜色信息,方便待会的赋予处理。

$fontcolor=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));

imagestring

把内容信息写到图片的相应位置上。

imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);

增加识别干扰

//增加点

// 生成一些干扰的点,这里是200个
for($i=0;$i<200;$i++){
  $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}

// 增加线

// 生成一些干扰线 这里是5个
for($i=0;$i<5;$i++){
  // 设置为浅色的线,防止喧宾夺主
  $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);

}

 数字字母混合验证码

<?php
// 使用gd的imagecreatetruecolor();创建一张背景图
$image = imagecreatetruecolor(100,40);

// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 将填充色填充到背景图上
imagefill($image,0,0,$bgcolor);

//////// 生成随机4位字母以及数字混合的验证码
for($i=0;$i<4;$i++){
  $fontsize = rand(6,8);
  $fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
  // 为了避免用户难于辨认,去掉了某些有歧义的字母和数字
  $rawstr = 'abcdefghjkmnopqrstuvwxyz23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
  $fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
  // 避免生成的图片重叠
  $x += 20;
  $y = rand(10,20);
  imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);  
}

// 生成一些干扰的点,这里是200个
for($i=0;$i<200;$i++){
  $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}
// 生成一些干扰线 这里是4个
for($i=0;$i<4;$i++){
  // 设置为浅色的线,防止喧宾夺主
  $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);

}


header('content-type:image/png');

imagepng($image);

// 释放资源,销毁执行对象
imagedestroy($image);

使用验证码

开启session的时机

注意: 开启session一定要在开始的地方 

验证的原理

验证的过程就是客户端输入的验证码和存在于session域中的验证码进行对比。即:

if(isset($_REQUEST['checkcode'])){
    session_start();
    if($_REQUEST['checkcode']==$_SESSION['checkcode']){
      echo "<font color='green'>Success!</font>"; 
    }else{
      echo "<font color='red'>Failed!</font>";  
    }
    exit();
  }

优化验证

但是简单的这样验证有一点不好的地方,那就是字母的大小写容易出错。所以我们要做一下转换,将用户输入的数值全部变成小写的。

if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){···}

小案例

生成验证码

<?php
session_start();// 必须在php的最开始部分声明,来开启session


// 使用gd的imagecreatetruecolor();创建一张背景图
$image = imagecreatetruecolor(100,40);

// 生成填充色
$bgcolor = imagecolorallocate($image,255,255,255);
// 将填充色填充到背景图上
imagefill($image,0,0,$bgcolor);

//////// 生成随机4位字母以及数字混合的验证码
$checkcode='';
for($i=0;$i<4;$i++){
  $fontsize = rand(6,8);
  $fontcolor = imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
  // 为了避免用户难于辨认,去掉了某些有歧义的字母和数字
  $rawstr = 'abcdefghjkmnopqrstuvwxyz23456789';
  $fontcontent = substr($rawstr,rand(0,strlen($rawstr)),1);
  // 拼接即将诞生的验证码
  $checkcode.=$fontcontent;
  // 避免生成的图片重叠
  $x += 20;
  $y = rand(10,20);
  imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);  
}
// 保存到session变量中
$_SESSION['checkcode']=$checkcode;

// 生成一些干扰的点,这里是200个
for($i=0;$i<200;$i++){
  $pointcolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imagesetpixel($image,rand(0,100),rand(0,30),$pointcolor);
}
// 生成一些干扰线 这里是4个
for($i=0;$i<4;$i++){
  // 设置为浅色的线,防止喧宾夺主
  $linecolor = imagecolorallocate($image,rand(50,255),rand(50,255),rand(50,255));
  imageline($image,rand(0,99),rand(0,29),rand(0,99),rand(0,29),$linecolor);

}


header('content-type:image/png');

imagepng($image);

// 释放资源,销毁执行对象
imagedestroy($image);

表单验证

<?php
header("Content-Type:text/html;charset=utf8");
    if(isset($_REQUEST['checkcode'])){
      session_start();
      if(strtolower($_REQUEST['checkcode'])==$_SESSION['checkcode']){
        echo "<font color='green'>Success!</font>"; 
      }else{
        echo "<font color='red'>Failed!</font>";  
      }
      exit();
    }
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>验证验证码信息</title>
  <script>
    function change(){
      document.getElementById("image_checkcode").src='./store.php?r='+Math.random(); 
    }
  </script>
</head>
<body>
<form action="./form.php" method="post">
<p>验证码图片:</p><img id="image_checkcode" src="./store.php?r=<?php echo rand();?>"  /><a href="javascript:void(0)" onclick="change()">看不清楚</a><br/>
请输入验证码<input type="text" name="checkcode" /><br />
<p><input type="submit" value="提交" /></p>


</form>

</body>
</html>

总结

最后,来个总结吧。
 •使用php制作验证码需要gd拓展的支持。
 •使用imagecreatetruecolor方法生成背景色,并用imagefill填充一个由imagecolorallocate产生的颜色。
 •使用imagestring来实现验证码和背景图的结合
 •使用imagesetpixel来添加干扰点
 •使用imageline来添加干扰线
 •使用session之前要在开头开启session_start()方法
 •使用JavaScript来动态的修改验证码的src,来满足用户“换一张”的需求。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
FirePHP 推荐一款PHP调试工具
Apr 23 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
May 19 PHP
CodeIgniter启用缓存和清除缓存的方法
Jun 12 PHP
PHP+JS实现大规模数据提交的方法
Jul 02 PHP
解决nginx不支持thinkphp中pathinfo的问题
Jul 21 PHP
php实现在站点里面添加邮件发送的功能
Apr 28 PHP
php利用gd库为图片添加水印
Nov 09 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
深入理解PHP的远程多会话调试
Sep 21 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
PHP实现文字写入图片功能
Feb 18 PHP
PHP实现简单用户登录界面
Oct 23 PHP
针对多用户实现头像上传功能PHP代码 适用于登陆页面制作
Aug 17 #PHP
总结PHP中数值计算的注意事项
Aug 14 #PHP
示例详解Laravel的注册重构
Aug 14 #PHP
PHP实现路由映射到指定控制器
Aug 13 #PHP
Yii2.0中的COOKIE和SESSION用法
Aug 12 #PHP
PHP Oauth授权和本地加密实现方法
Aug 12 #PHP
PHP 读取大文件并显示的简单实例(推荐)
Aug 12 #PHP
You might like
《星际争霸II》全新指挥官斯台特曼现已上线
2020/03/08 星际争霸
虫族 Zerg 热键控制
2020/03/14 星际争霸
discuz论坛 用户登录 后台程序代码
2008/11/27 PHP
Zend的MVC机制使用分析(二)
2013/05/02 PHP
PHP7.1实现的AES与RSA加密操作示例
2018/06/15 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
php实现session共享的实例方法
2019/09/19 PHP
JScript中的&quot;this&quot;关键字使用方式补充材料
2007/03/08 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
Javascript实现跑马灯效果的简单实例
2016/05/31 Javascript
js实现表格筛选功能
2017/01/18 Javascript
详解vue-cli 构建项目 vue-cli请求后台接口 vue-cli使用axios、sass、swiper
2018/05/28 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
2018/09/17 Javascript
微信小程序实现列表页的点赞和取消点赞功能
2018/11/02 Javascript
JavaScript常用工具方法封装
2019/02/12 Javascript
ES6中new Function()语法及应用实例分析
2020/02/19 Javascript
vue实现移动端返回顶部
2020/10/12 Javascript
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
Python 自动安装 Rising 杀毒软件
2009/04/24 Python
python高并发异步服务器核心库forkcore使用方法
2013/11/26 Python
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
python生成指定尺寸缩略图的示例
2014/05/07 Python
python类和继承用法实例
2015/07/07 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
2016/08/28 Python
Python入门_学会创建并调用函数的方法
2017/05/16 Python
创建pycharm的自定义python模板方法
2018/05/23 Python
详解用Python为直方图绘制拟合曲线的两种方法
2019/08/21 Python
vim自动补全插件YouCompleteMe(YCM)安装过程解析
2019/10/21 Python
使用Bazel编译TensorBoard教程
2020/02/15 Python
pycharm 使用tab跳出正在编辑的括号(){}{}等问题
2021/02/26 Python
英语专业毕业生求职简历的自我评价
2013/10/24 职场文书
秋季运动会稿件
2014/01/30 职场文书
协议书怎么写
2014/04/21 职场文书
快餐公司创业计划书
2014/04/29 职场文书
村班子对照检查材料
2014/08/18 职场文书
中英文求职信范文
2015/03/19 职场文书