yii框架整合smarty使用自定义验证码

文章目录
  1. 1. 前言
  2. 2. 设计思路
  3. 3. 项目结构
  4. 4. 代码实现
  5. 5. 使用
    1. 5.1. 接口
    2. 5.2. 显示
    3. 5.3. 刷新
    4. 5.4. 验证
    5. 5.5. 效果演示
  6. 6. 源码分享
  7. 7. 书签

前言

把模板引擎换成smarty后,yii框架自带的captcha,非常不友好,使用起来不方便。干脆自己封装一个php图片验证码模块,想要移植到其他框架,简单修改即可。

设计思路

PHP生成验证码的原理:使用PHP的GD库,生成一张带验证码的图片,并将验证码保存在Session中。PHP生成验证码的大致流程有:

1、产生一张png的图片;

2、为图片设置背景色;

3、设置字体颜色和样式;

4、产生N位数的随机的验证码;

5、把产生的每个字符调整旋转角度和位置画到png图片上;

6、加入噪点和干扰线防止注册机器分析原图片来恶意破解验证码;

7、输出图片;

8、释放图片所占内存。

项目结构

1、《yii框架实战》的基础上,在controllers目录中新建util目录,util目录中新建CaptchaController.php,用来实现验证码模块。

2、在web中新建font目录,font目录中放入微软雅黑字体msyh.ttf,用来显示验证码上的字体。

代码实现

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
<?php

namespace app\controllers\util;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;

class CaptchaController extends Controller
{
public function actionIndex()
{
echo 'captcha index function';
}

public function actionGetcode(){
session_start();
$response = Yii::$app->getResponse();
$response->format = $response::FORMAT_RAW;
$this->createCode(300,80,30);
}

public function createCode($width,$height,$fontsize){
//设置验证码图片大小的函数
$image = imagecreate($width, $height);
//设置验证码颜色 imagecolorallocate(int im, int red, int green, int blue);
$bgcolor = imagecolorallocate($image,255,255,255); //#fff
//区域填充 int imagefill(int im, int x, int y, int col) (x,y) 所在的区域着色,col 表示欲涂上的颜色
imagefill($image, 0, 0, $bgcolor);

//设置变量
$captcha_code = "";
//生成随机的字母和数字
for($i=0;$i<4;$i++){

//设置字体颜色,随机颜色,0-120深颜色
$fontcolor = imagecolorallocate($image, rand(0,120),rand(0,120), rand(0,120));
//$fontcolor = imagecolorallocate($image, 0, 0, 0);
//设置需要随机取的值,去掉容易出错的值如0和o、1和l、2和z
$data ='abcdefghigkmnpqrstuvwxy3456789';
//取出值,字符串截取方法 strlen获取字符串长度
$fontcontent = substr($data, rand(0,strlen($data)-1),1);
//连续定义变量
$captcha_code .= $fontcontent;

//imagestring设置字体大小,最大值为5
//$fontsize = 5;

//设置坐标
$x = ($i*$width/4)+rand(5,10);
$y = rand(($height+$fontsize)/2-5,($height+$fontsize)/2+5);
//imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
imagettftext($image,$fontsize,rand(-10,10),$x,$y,$fontcolor,'font/msyh.ttf',$fontcontent);
}
//存到session
$_SESSION['captcha_code'] = $captcha_code;
//增加干扰元素,设置雪花点
for($i=0;$i<200;$i++){
//设置点的颜色,50-200颜色比数字浅,不干扰阅读
$pointcolor = imagecolorallocate($image,rand(50,200), rand(50,200), rand(50,200));
//imagesetpixel — 画一个单一像素
imagesetpixel($image, rand(1,$width-1), rand(1,$height-1), $pointcolor);
}
//增加干扰元素,设置横线
for($i=0;$i<2;$i++){
//设置线的颜色
$linecolor = imagecolorallocate($image,rand(80,220), rand(80,220),rand(80,220));
//设置线,两点一线
imageline($image,rand(1,$width-1), rand(1,$height-1),rand(1,$width-1), rand(1,$height-1),$linecolor);
}

//设置头部,image/png
header('Content-Type: image/png');
//imagepng() 建立png图形函数
imagepng($image);
//imagedestroy() 结束图形函数 销毁$image
imagedestroy($image);
}

public function actionCheck($code){
session_start();
if(isset($_SESSION['captcha_code'])){
if($_SESSION['captcha_code'] == $code){
unset($_SESSION['captcha_code']);
$result = array(
'code'=> '0',
'ext'=> '验证成功'
);
}else{
$result = array(
'code'=> '1',
'ext'=> '验证码错误'
);
}
}else{
$result = array(
'code'=> '2',
'ext'=> '请先刷新验证码'
);
}

echo json_encode($result,JSON_UNESCAPED_UNICODE);
}
}

使用

接口

获取验证码接口:http://localhost/basic/web/util/captcha/getcode

验证验证码接口:http://localhost/basic/web/util/captcha/check?code=f7nh

显示

在smarty渲染的页面中,直接使用验证码接口即可显示图片。

1
2
3
<p><img id="captcha" src="http://localhost/basic/web/util/captcha/getcode" alt=""></p>
<p>请输入验证码:<input id="code" type="text"></p>
<p><input id="check" type="button" value="确定"></p>

刷新

如果要刷新验证码,在js中重置src地址即可。

1
2
3
4
$('#captcha').click(function(){
var $new_src = 'http://localhost/basic/web/util/captcha/getcode?'+Math.random();
$(this).attr('src',$new_src);
});

验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$('#check').click(function(){
var data = {
code: $('#code').val()
};
$.ajax({
url: 'http://localhost/basic/web/util/captcha/check',
type: 'GET',
dataType: 'json',
data: data,
success: function(data){
alert(data.ext);
},
error: function(xhr){
console.log(xhr);
}
});
});

效果演示

源码分享

1、下载安装:git clone https://github.com/voidking/yii-basic.git basic

2、利用navicat等工具连接到本地mysql数据库,创建数据库basic,在数据库中创建表bas_project(int id, varchar title, varchar content)。注意,编码格式选择utf8。

3、验证码测试页url:
http://localhost/basic/web/util/captcha/index

书签

PHP生成各种验证码和Ajax验证

PHP如何实现验证码