基于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 相关文章推荐
如何获知PHP程序占用多少内存(memory_get_usage)
Sep 23 PHP
thinkphp的c方法使用示例
Feb 24 PHP
PHP开发框架kohana3 自定义路由设置示例
Jul 14 PHP
php从完整文件路径中分离文件目录和文件名的方法
Mar 13 PHP
php按字符无乱码截取中文的方法
Mar 27 PHP
PHP中list()函数用法实例简析
Jan 08 PHP
PHP中spl_autoload_register()函数用法实例详解
Jul 18 PHP
PHP对象实例化单例方法
Jan 19 PHP
PHP实现的注册,登录及查询用户资料功能API接口示例
Jun 06 PHP
php实现微信公众号企业转账功能
Oct 01 PHP
laravel使用数据库测试注意事项
Apr 10 PHP
php+js实现点赞功能的示例详解
Aug 07 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 iconv() : Detected an illegal character in input string
2010/12/05 PHP
php自定义函数实现二维数组按指定key排序的方法
2016/09/29 PHP
PHP文件上传处理案例分析
2016/10/15 PHP
PHP图片水印类的封装
2017/07/06 PHP
将Datatable转化成json发送前台实现思路
2013/09/06 Javascript
jquery删除提示框弹出是否删除对话框
2014/01/07 Javascript
深入理解JavaScript系列(26):设计模式之构造函数模式详解
2015/03/03 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
js中遍历对象的属性和值的方法
2016/07/27 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
2017/12/09 Javascript
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
原生JS实现自定义下拉单选选择框功能
2018/10/12 Javascript
解决JavaScript中0.1+0.2不等于0.3问题
2018/10/23 Javascript
vue通过cookie获取用户登录信息的思路详解
2018/10/30 Javascript
vue 检测用户上传图片宽高的方法
2020/02/06 Javascript
Python3.x和Python2.x的区别介绍
2013/02/12 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
2016/08/28 Python
Python做简单的字符串匹配详解
2017/03/21 Python
Python用imghdr模块识别图片格式实例解析
2018/01/11 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
python创建文件备份的脚本
2018/09/11 Python
python超时重新请求解决方案
2019/10/21 Python
tensorflow之并行读入数据详解
2020/02/05 Python
解决Keras自带数据集与预训练model下载太慢问题
2020/06/12 Python
Mytheresa中国官网:德国时尚奢侈品商城
2017/08/04 全球购物
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
Happy Plugs官网:瑞典无线耳机品牌
2020/07/16 全球购物
shell程序中如何注释
2012/02/17 面试题
“四风”问题自我剖析材料思想汇报
2014/09/23 职场文书
单位计划生育责任书
2015/05/09 职场文书
如何计划开一家便利店?
2019/07/31 职场文书
node.js使用express-fileupload中间件实现文件上传
2021/07/16 Javascript
Python天气语音播报小助手
2021/09/25 Python
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers