0%

PHP高级特性七之验证码操作

综述

对于PHP的图像处理来说,应用最广泛的便是验证码处理了,上一节我们学习到了PHP绘图的一些基本操作。现在我们实际运用一下,来感受一下验证码的相关应用。 在这里,我们将整个验证码写成了一个PHP类,以后我们用的时候直接调用这个类就好了。 传入的参数为验证码的宽度,高度,还有验证码的字符。

验证码类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php

class Code {
//验证码的宽度
private $width;
//验证码的高度
private $height;
//验证码字符的个数
private $codeNum;
//图像资源
private $image;
//干扰点的个数
private $disturbColorNum;
//验证码字符内容
private $checkCode;

//构造方法,默认宽为80,高为20,字符个数为4
function __construct($width=80, $height=20, $codeNum=4){
//赋值成员变量
$this->width=$width;
$this->height=$height;
$this->codeNum=$codeNum;
//获得验证码字符内容
$this->checkCode=$this->createCheckCode();
//设置干扰点的个数
$number=floor($width*$height/15);
if($number > 240-$codeNum){
$this->disturbColorNum= 240-$codeNum;
}else{
$this->disturbColorNum=$number;
}
}

//通过访问该方法向浏览器中输出图像
function showImage($fontFace=""){
//第一步:创建图像背景
$this->createImage();
//第二步:设置干扰元素
$this->setDisturbColor();
//第三步:向图像中随机画出文本
$this->outputText($fontFace);
//第四步:输出图像
$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(){
//创建干扰的点
for($i=0; $i<$this->disturbColorNum; $i++){
$color=imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
imagesetpixel($this->image, rand(1, $this->width-2), rand(1, $this->height-2), $color);
}
//创建干扰的线条
for($i=0; $i<10; $i++){
$color=imagecolorallocate($this->image, rand(200, 255), rand(200, 255), rand(200, 255));
imagearc($this->image, rand(-10, $this->width), rand(-10, $this->height), rand(30, 300), rand(20, 200), 55, 44, $color);
}
}

//创建随机验证码
private function createCheckCode(){
$code="23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ";
$string='';
//从字符串中取出随机的字符
for($i=0; $i < $this->codeNum; $i++){
$char=$code{rand(0, strlen($code)-1)};
$string.=$char;
}
//返回字符内容
return $string;
}

//设置验证码的字符
private function outputText($fontFace=""){
for($i=0; $i<$this->codeNum; $i++){
$fontcolor=imagecolorallocate($this->image, rand(0, 128), rand(0, 128), rand(0, 128));
if($fontFace==""){
$fontsize=rand(3, 5);
$x=floor($this->width/$this->codeNum)*$i+3;
$y=rand(0, $this->height-15);
imagechar($this->image,$fontsize, $x, $y, $this->checkCode{$i},$fontcolor);
}else{
$fontsize=rand(12, 16);
$x=floor(($this->width-8)/$this->codeNum)*$i+8;
$y=rand($fontSize+5, $this->height);
imagettftext($this->image,$fontsize,rand(-30, 30),$x,$y ,$fontcolor, $fontFace, $this->checkCode{$i});
}
}
}

//输出验证码图像资源
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.class.php, 下面我们来看一下怎样应用。

实际应用

我们写好了这个类之后,该怎么来调用呢?我们写一个demo如下

1
2
3
4
5
6
7
<?php
session_start();
include "code.class.php";
$code=new Code(80, 20, 4);
$code->showImage(); //输出到页面中供 注册或登录使用
$_SESSION["code"]=$code->getCheckCode(); //将验证码保存到服务器中
?>

这段代码声明了一个code对象,然后调用 showImage 方法,显示出验证码,最后通过getCheckCode 方法,获得验证码字符串的内容,保存到了 session 全局变量中。 以上代码我们保存成 code.php 文件 之后,我们写一个表单来提交验证一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
session_start();
if(@$_POST["code"]&&strtoupper($_POST["code"])==strtoupper($_SESSION["code"])){
echo "ok";
}else{
echo "error";
}
?>
<body>
<form action="login.php" method="post">
code: <input type="text" name="code"> <img src="code.php" onclick="this.src='code.php?'+Math.random()"><br>
<input type="submit" name="sub" value="login"><br>
</form>
</body>

上面的代码包括了一个输入框还有验证码,验证码的 src 资源可以直接引用为 code.php 文件,这里需要注意的是,后面要加一个参数,防止因为浏览器缓存原因而导致验证码无法更换。 最后表单是提交到文件本身,所以就可以比较提交的数据和 session 全局变量之间的关系,如果相同输出 ok,如果不同输出 error 小伙伴可以验证一下!希望对大家有帮助!