说在前头:本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,能力有限,文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正。若在阅读时有任何的问题,也可通过评论提出,本人将根据自身能力对问题进行一定的解答。
前言
验证码的作用:网站上的验证码的作用是保护网站安全,一般网站都要通过验证码来防止机器大规模注册,机器暴力破解数据密码等危害。手机的短信和语音验证码是要确定这个手机是用户自己的。其实最后都是为了验证,这个操作是个人在做而不是机器,证明我是我的过程。接下来我们就通过PHP的GD库生成一个图形验证码。
制作图形验证码前对技能储备的要求:对php,和html的语法有一定的了解。
1.开启PHP的GD库扩展
使用GD库制作验证码前,需要开启PHP的GD库扩展,我们可以通过phpinfo();函数查看自己的php是否已经开启GD库扩展(如下)
接着我们访问在浏览器访问http://localhost/info.php即可查看到如下界面
按下浏览器自带的查找关键字的快捷键ctrl+f,搜索gd,如下:
搜索结果如上,即您的php已启用GD库扩展,如果没有上面所示的信息,说明php的GD库还未启用,我们需要手动开启GD库扩展。
找到php安装目录,我这边使用的是NMP集成环境,对应的目录为D:\Visual-NMP-x64\Bin\PHP\php-7.0.13-nts-Win32-VC14-x64(路径只用于参考)。
找到安装目录后,我们可以找到php的配置文件php.ini(如下图)
打开php.ini文件,找到php_gd2.dll,将该行前的分号“;”去掉,表明你要开启php的GD库。(如下图)
2.制作前端页面
由于我们现在只是对制作图形验证码做测试,对于前端的页面我们做的简单一点即可。
前端页面分为主页index.php,以及通知提醒的alert.php两个页面,页面代码可以参考下面的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
<style>
form {
position: absolute;
text-align: center;
width: 160px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
input {
width: 160px;
}
h4 {
color: deepskyblue;
}
#submit {
border-radius: 5px;
color: white;
width: 160px;
height: 30px;
font-weight: bold;
background: deepskyblue;
}
img {
width: 160px;
height: 30px;
border: 1px solid gray;
}
</style>
</head>
<body>
<form method="post" action="check.php">
<h4>登 录 页 面</h4>
<input name="username" type="text" placeholder="用户名"/>
<br/><br/>
<input name="password" type="password" placeholder="密码"/>
<br/><br/>
<input name="captcha" type="text" placeholder="验证码"/>
<br/><br/>
<img src="captcha.php">
<br/><br/>
<input id="submit" type="submit" value="登录">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>提示</title>
</head>
<body>
<script>
alert("<?php echo $_GET['msg'] ?>");
history.back();
</script>
</body>
</html>
访问http://localhost/,我们可以看到前端页面效果如下
3.主要函数介绍
imagecreatetruecolor(); // 生成画布函数
imagecolorallocate(); // 设置背景颜色函数
imagefill(); // 画面填充函数
imagesetpixel(); // 生成点图形的函数
imageline(); // 生成线条图形的函数
header('content-type:image.png');// 设置图片输出格式为png
imagepng($image); // 以png的格式输出图片
imagedestroy($image); // 销毁图片
4.开始制作验证码
①:创建captcha.php文件用于生成验证码图片
②:创建画布
<?php
// 创建宽为160px,高为30px的画布
$image = imagecreatetruecolor(160, 30);
// 设置背景颜色为白色
$bg_color = imagecolorallocate($image, 255, 255, 255);
imagefill($image,0,0,$bg_color);
// 以png的格式输出
header('content-type:image.png');
imagepng($image);
// 销毁图片
imagedestroy($image);
?>
访问http://localhost/,我们可以看到,页面已经生成了一张全白的验证码图片
③:接下来我们需要对空白的验证码图片中添加验证码信息,代码如下
<?php
// 创建宽为160px,高为30px的画布
$image = imagecreatetruecolor(160, 30);
// 设置背景颜色为白色
$bg_color = imagecolorallocate($image, 255, 255, 255);
imagefill($image,0,0,$bg_color);
// 字母和数字混合验证码
for($i = 0; $i < 4; $i++) {
$font_size = 10;
$font_color = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120));
$data = 'abcdefghijklmnopqrstuvwxyz1234567890';// 验证码字典
$font_content = substr($data, rand(0, strlen($data)), 1);
$x = ($i * 160 / 4) + rand(5, 10);
$y = rand(5, 10);
imagestring($image, $font_size, $x, $y, $font_content, $font_color);
}
// 以png的格式输出
header('content-type:image.png');
imagepng($image);
// 销毁图片
imagedestroy($image);
?>
访问http://localhost/,空白的画布上已经出现了四位字母和数字混合的验证码信息。
④:我们还需要对验证码添加以下干扰因素(降低机器识别验证码的成功概率),先加数十位颜色各异的点(代码如下)
<?php
// 创建宽为160px,高为30px的画布
$image = imagecreatetruecolor(160, 30);
// 设置背景颜色为白色
$bg_color = imagecolorallocate($image, 255, 255, 255);
imagefill($image,0,0,$bg_color);
// 字母和数字混合验证码
for($i = 0; $i < 4; $i++) {
$font_size = 10;
$font_color = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120));
$data = 'abcdefghijklmnopqrstuvwxyz1234567890';// 验证码字典
$font_content = substr($data, rand(0, strlen($data)), 1);
$x = ($i * 160 / 4) + rand(5, 10);
$y = rand(5, 10);
imagestring($image, $font_size, $x, $y, $font_content, $font_color);
}
// 增加干扰点
for($i = 0 ; $i < 200; $i++){
$point_color = imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
imagesetpixel($image, rand(1, 159), rand(1, 29), $point_color);//
}
// 以png的格式输出
header('content-type:image.png');
imagepng($image);
// 销毁图片
imagedestroy($image);
?>
访问http://localhost/,验证码图片在原来的基础上,增多了许多干扰点
⑤:为了进一步降低机器识别验证码的成功概率,最后我们再添加几条干扰线,代码如下
<?php
// 创建宽为160px,高为30px的画布
$image = imagecreatetruecolor(160, 30);
// 设置背景颜色为白色
$bg_color = imagecolorallocate($image, 255, 255, 255);
imagefill($image,0,0,$bg_color);
// 字母和数字混合验证码
for($i = 0; $i < 4; $i++) {
$font_size = 10;
$font_color = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120));
$data = 'abcdefghijklmnopqrstuvwxyz1234567890';// 验证码字典
$font_content = substr($data, rand(0, strlen($data)), 1);
$x = ($i * 160 / 4) + rand(5, 10);
$y = rand(5, 10);
imagestring($image, $font_size, $x, $y, $font_content, $font_color);
}
// 增加干扰点
for($i = 0 ; $i < 200; $i++){
$point_color = imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
imagesetpixel($image, rand(1, 159), rand(1, 29), $point_color);//
}
// 增加干扰线
for($i = 0; $i < 3; $i++){
$line_color = imagecolorallocate($image, rand(80, 280), rand(80, 220), rand(80, 220));
imageline($image, rand(1, 159), rand(1, 29), rand(1, 99), rand(1, 29), $line_color);
}
// 以png的格式输出
header('content-type:image.png');
imagepng($image);
// 销毁图片
imagedestroy($image);
?>
访问http://localhost/,验证码图片成为了我们想要的摸样了
至此,我们的验证码图片已经完善,但对于验证码信息的判断我们一直未思考,我们需要使用一个全局的变量保存验证码信息,然后使用这个全局的变量与用户的输入的验证码信息进行判断。在浏览器中我们有什么是全局的变量?我们可以使用session保存我们的变量,当需要与用户输入的验证码验证时,从session中取出与之匹配。
⑥:对此我们对我们的captcha.php代码进行修改,如下:
<?php
session_start();// 开启会话
// 创建宽为160px,高为30px的画布
$image = imagecreatetruecolor(160, 30);
// 设置背景颜色为白色
$bg_color = imagecolorallocate($image, 255, 255, 255);
imagefill($image,0,0,$bg_color);
$captcha='';// 存储验证码
// 字母和数字混合验证码
for($i = 0; $i < 4; $i++) {
$font_size = 10;
$font_color = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120));
$data = 'abcdefghijklmnopqrstuvwxyz1234567890';
$font_content = substr($data, rand(0, strlen($data)), 1);
$captcha.=$font_content;
$x = ($i * 160 / 4) + rand(5, 10);
$y = rand(5, 10);
imagestring($image, $font_size, $x, $y, $font_content, $font_color);
}
// 使用session保存验证码信息,用于后续验证
$_SESSION['captcha']=$captcha;
// 增加干扰点
for($i = 0 ; $i < 200; $i++){
$point_color = imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
imagesetpixel($image, rand(1, 159), rand(1, 29), $point_color);//
}
// 增加干扰线
for($i = 0; $i < 3; $i++){
$line_color = imagecolorallocate($image, rand(80, 280), rand(80, 220), rand(80, 220));
imageline($image, rand(1, 159), rand(1, 29), rand(1, 99), rand(1, 29), $line_color);
}
// 以png的格式输出
header('content-type:image.png');
imagepng($image);
// 销毁图片
imagedestroy($image);
?>
至此,captcha.php文件生成验证码的代码已经完善。
4.后台验证
创建check.php文件做后台逻辑处理验证(用户名与密码使用固定的test:123456),代码如下:
<?php
session_start();// 开启会话
$db_username = "test";
$db_password = "123456";
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$captcha = $_REQUEST['captcha'];
if ($username == "" || $password == "") {
header('location:alert.php?msg=用户名密码不能为空');
exit();
}
if ($captcha == "") {
header('location:alert.php?msg=验证码不能为空');
exit();
}
if ($captcha != $_SESSION['captcha']) {
header('location:alert.php?msg=验证码错误');
exit();
}
if ($db_username == $username && $db_password == $password) {
header('location:alert.php?msg=登录成功');
exit();
}
header('location:alert.php?msg=登录失败');
?>
5.测试
访问http://localhost/,开始进行测试。
可以看到,验证码内容为,"6d9o",此时我们输入在用户名处输入test,密码输入123456,验证码为空,点击登录后会得到以下提示(“验证码不能为空”)。
接下来,输入错的验证码
点击登录,得到提示(“验证码错误”)。
输入正确验证码点击登录
得到提示(“登录成功”)。
总结
相信对于php与html语法有基本了解的小伙伴们,此技术应该很好理解,也希望此文章对你们有所帮助。若文章中有错漏之处,还请您的斧正。
👇扫描二维码关注