基于Zend的Captcha机制的应用


Posted in PHP onMay 02, 2013

如何生成验证码图片?使用php的GD? ok,right。其实Zend的Captcha模块已经封装好了。这篇文章就说一下如何使用Zend的Captcha模块。

环境安装
首先Zend的Captcha需要安装GD。查看有没有安装GD需要去phpinfo()中看是否有GD模块。(注意,有可能出现php -m里面的模块有gd但phpInfo()里面的模块没有gd,这个问题是说明你的PHP和Apache没有安装对。具体请去google之)

(如果在安装gd的过程中提示Missing Dependency: libt1.so.5模块错误,请看这篇文章:http://www.siutung.org/post/730/)

生成验证码图片
使用Zend_Captcha_Image类

$captcha = new Zend_Captcha_Image(); 
$captcha->setWordLen('4') 
    ->setHeight('60') 
    ->setFont(NCHANNEL_FONT_DIR . '/arial.ttf') 
    ->setImgDir(NCHANNEL_CAPTCHA_DIR) 
    ->setDotNoiseLevel('5') 
    ->setLineNoiseLevel('5'); $id = $captcha->generate(); 
$code = $captcha->getWord();

1 这里有两个变量需要说一下,$id 和 $code。

图片文件名就是$id . ".png"; 这个id是一个随机数。

$code是这个图片中的文字,就是验证码的答案

2 setWordLen 等设置的接口是Zend_Captcha_Image暴露给外面的对验证码图片的设置。其实看函数名也能知道是做什么的了。具体请参考Zend的Api手册。

3 font字体文件必须在服务器上有,ImgDir设置的是图片生成路径
 

验证验证码图片
好了,生成了验证码图片,现在要验证验证码了。

验证步骤就需要用到Zend_Session_Namespace这个session存储模块。

首先,生成验证码的时候有id和code两个变量应该存下来。
好吧,回到上一步,将代码进行下修改

$captcha = new Zend_Captcha_Image(); 
$captcha->setWordLen('4') 
    ->setHeight('60') 
    ->setFont(NCHANNEL_FONT_DIR . '/arial.ttf') 
    ->setImgDir(NCHANNEL_CAPTCHA_DIR) 
    ->setDotNoiseLevel('5') 
    ->setLineNoiseLevel('5'); $id = $captcha->generate(); 
$codeSession = new Zend_Session_Namespace('captcha_code_' . $id); 
$codeSession->code = $captcha->getWord();

这里看到,我们使用$captcha_code_$id将code存储下来。目的是等到验证步骤的时候使用。

第二步
给页面传递表单的时候把$id和验证码图片传递过去。

让用户填写验证码。

第三步,验证。
验证这步需要用户提供两个参数: $id 和验证码答案$code

$codeSession = new Zend_Session_Namespace('captcha_code_' . $this->_params['id']); 
if ($codeSession == null || strtolower($codeSession->code) != strtolower($this->_params['code'])) { 
    $this->Output(ERROR); }

这段代码读起来很顺口吧:如果captcha_code_$id中有保存code,并且code和用户填写的code一致,那么就验证成功。

这样,验证码验证过程就结束了。

深入考虑
好了,其实验证码没有这么简单。下面有几个问题值得考虑

验证码图片是不会自动删除的,所以生成的验证码图片所在文件夹体积会不断增加。怎么办?
Image类中是提供了方法的$captcha->setGcFreq(5) 。

具体使用方法看API吧

我希望自己设置$id,怎么办?
答案是在Zend_Captche_Image上再封装一层,然后重写generate()方法

比如我重写了一个类:

class Test_Captcha_Image extends Zend_Captcha_Image 
{ 
    protected $_fid = "";     public function generate() 
    { 
        $word = $this->_generateWord(); 
        $this->_setWord($word); 
        if ($this->_fid) { 
            $id = $this->_fid; 
        } 
        $this->_generateImage($id, $this->getWord()); 
        if (mt_rand(1, $this->getGcFreq()) == 1) { 
            $this->_gc(); 
        } 
        return $id; 
    } 
    public function setId($id) { 
        $this->_fid = $id; 
        return $this; 
    } 
}

我希望我每个用户只有一个验证码,这个验证码的图片名称就是userid.png
 

那么使用这个类的代码是这样的

$captcha = new Test_Captcha_Image(); 
$captcha->setWordLen('4') 
    ->setHeight('60') 
    ->setFont(NCHANNEL_FONT_DIR . '/arial.ttf') 
    ->setImgDir(NCHANNEL_CAPTCHA_DIR) 
    ->setDotNoiseLevel('5') 
    ->setLineNoiseLevel('5') 
    ->setId($user_id); $id = $captcha->generate(); 
$codeSession = new Zend_Session_Namespace('captcha_code_' . $user_id); 
$codeSession->code = $captcha->getWord(); 
--------------   
// 验证session 
$codeSession = new Zend_Session_Namespace('captcha_code_' . $this->_params['user_id']); 
if ($codeSession == null || strtolower($codeSession->code) != strtolower($this->_params['code'])) { 
    $this->Output(ERROR); 
}

附言
Zend的Captcha是封装了基本的验证码动作。生成简单的验证码基本是完全不需要看内部的代码的了,但如果你需要对验证码进行更高级的操作,比如修改验证码的显示文字等,最好就需要将Captcha的源码看一下了。
PHP 相关文章推荐
Mysql的常用命令
Oct 09 PHP
如何在PHP中使用Oracle数据库(1)
Oct 09 PHP
教你如何把一篇文章按要求分段
Oct 09 PHP
PHP 开发工具
Dec 06 PHP
一组PHP加密解密函数分享
Jun 05 PHP
php批量删除数据库下指定前缀的表以prefix_为例
Aug 24 PHP
php基于表单密码验证与HTTP验证用法实例
Jan 06 PHP
php header函数的常用http头设置
Jun 25 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
Jan 07 PHP
php中访问修饰符的知识点总结
Jan 27 PHP
Laravel5框架自定义错误页面配置操作示例
Apr 17 PHP
jQuery+PHP实现图片上传并提交功能
Jul 27 PHP
PHP静态调用非静态方法的应用分析
May 02 #PHP
Mysql中分页查询的两个解决方法比较
May 02 #PHP
记录mysql性能查询过程的使用方法
May 02 #PHP
基于MySQL分区性能的详细介绍
May 02 #PHP
php中使用$_REQUEST需要注意的一个问题
May 02 #PHP
PHP执行批量mysql语句的解决方法
May 02 #PHP
PHP闭包(Closure)使用详解
May 02 #PHP
You might like
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
2013/04/26 PHP
PHP解决URL中文GBK乱码问题的两种方法
2014/06/03 PHP
DOM 基本方法
2009/07/18 Javascript
jQuery EasyUI API 中文文档 - Menu菜单
2011/10/03 Javascript
jquery 延迟执行实例介绍
2013/08/20 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
jQuery中ajax的load()方法用法实例
2014/12/26 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
vue 2.x 中axios 封装的get 和post方法
2018/02/28 Javascript
vue + webpack如何绕过QQ音乐接口对host的验证详解
2018/07/01 Javascript
three.js利用卷积法如何实现物体描边效果
2019/11/27 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
2020/02/11 Javascript
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
[59:59]EG vs IG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python 不同对象比较大小示例探讨
2014/08/21 Python
python批量修改文件名的实现代码
2014/09/01 Python
Python中join和split用法实例
2015/04/14 Python
利用aardio给python编写图形界面
2017/08/21 Python
python中Matplotlib实现绘制3D图的示例代码
2017/09/04 Python
Python利用turtle库绘制彩虹代码示例
2017/12/20 Python
基于Python socket的端口扫描程序实例代码
2018/02/09 Python
python模块smtplib学习
2018/05/22 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
python3+selenium实现126邮箱登陆并发送邮件功能
2019/01/23 Python
Python 用__new__方法实现单例的操作
2020/12/11 Python
CSS3教程(10):CSS3 HSL声明设置颜色
2009/04/02 HTML / CSS
HTML5 通过Vedio标签实现视频循环播放的示例代码
2020/08/05 HTML / CSS
HMV日本官网:全球知名的音乐、DVD和电脑游戏零售巨头
2016/08/13 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
旅游管理毕业生自荐信
2013/11/05 职场文书
保险专业自荐信范文
2014/02/20 职场文书
高三语文复习计划
2015/01/19 职场文书
《画家和牧童》教学反思
2016/02/17 职场文书
2016年党员创先争优承诺书
2016/03/25 职场文书
60句有关成长的名言
2019/09/04 职场文书