前段时间做登陆功能,涉及到了一个验证码的插件。想到Yii框架自带的一个CCaptcha的扩展,轻松许多。
1、先用CActiveForm做了个登陆的表单,
2、然后往里面添加一个CCaptcha的widget
-
验证码:
-
$this->widget('CCaptcha', array(
'imageOptions' => array('style' => 'cursor:pointer;width:70px;height:30px;display:inline-block;','id' => 'veryCode'),
'clickableImage' => true,
'buttonLabel' => '换一张',
));
?>
<?php echo $form->textField($model,'verifyCode'); ?>
<?php echo $form->error($model, 'verifyCode', array('class'=>'tso'),false,false); ?>
表单组合出来后的效果图:
看似不错,但是测试后发现验证码怎么输入都提示错误。想不明白,我是完全按照手册API上的步骤做的,不可能会有错误啊。
百度/谷歌无果后,决定仔细看一下这个CCaptcha内部的结构。
既然验证码只是起到一个验证的功能,那就先看看它的验证过程。
找到 CCaptchaAction::validate()这个方法,发现有这么一行代码:
$session[$name] = $session[$name] + 1;
if($session[$name] > $this->testLimit && $this->testLimit > 0)
$this->getVerifyCode(true); 其中$session[$name]记录了验证码的使用次数。
发现问题了,我设置了testLimit这个参数等于1。而且,登陆表单还打开了ajax验证以及提交前验证功能。
知道问题在哪了吧,testLimit表示这个验证码只能用一次,而表单的Ajax过程中验证了很多次了,导致系统中的验证码早就更换了,而页面中展示的还是第一次生成的验证码图片。
解决这个问题的办法就是让验证码在ajax提交的时候不执行$session[$name] = $session[$name] + 1;这一行。
根本原因找到后就开始解决这个问题。代码如下:
/**
* @author xiaobo
* 继承自yii自带的CCaptchaAction
* 如果是ajax提交则不记录提交次数
* example code:
class SiteController extends QController
{
public function actions()
{
return array(
// 验证码
'captcha' => array(
'class' => 'webroot.protected.extensions.captcha.glcaptchaAction',
),
);
}
}
*/
class glcaptchaAction extends CCaptchaAction
{
public function validate($input,$caseSensitive)
{
$code = $this->getVerifyCode();
$valid = $caseSensitive ? ($input === $code) : !strcasecmp($input,$code);
$session = Yii::app()->session;
$session->open();
$name = $this->getSessionKey() . 'count';
if(!Yii::app()->request->isAjaxRequest){
$session[$name] = $session[$name] + 1;
}
if($session[$name] > $this->testLimit && $this->testLimit > 0){
$this->getVerifyCode(true);
}
return $valid;
}
}
?>
至此,验证码不再‘飘忽不定’。一切都这么美好!!!