前段時間作登錄功能,涉及到了一個驗證碼的插件。想到Yii框架自帶的一個CCaptcha的擴展,輕鬆許多。 php
一、先用CActiveForm作了個登錄的表單, web
二、而後往裏面添加一個CCaptcha的widget ajax
<dl class="intxt yz"> <dt>驗證碼:</dt> <dd> <?php $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'); ?> <span class="msg"><i></i><?php echo $form->error($model, 'verifyCode', array('class'=>'tso'),false,false); ?></span> </dd> </dl>
表單組合出來後的效果圖: session
看似不錯,可是測試後發現驗證碼怎麼輸入都提示錯誤。想不明白,我是徹底按照手冊API上的步驟作的,不可能會有錯誤啊。 app
百度/谷歌無果後,決定仔細看一下這個CCaptcha內部的結構。 框架
既然驗證碼只是起到一個驗證的功能,那就先看看它的驗證過程。 yii
找到 CCaptchaAction::validate()這個方法,發現有這麼一行代碼: 測試
$session[$name] = $session[$name] + 1; if($session[$name] > $this->testLimit && $this->testLimit > 0) $this->getVerifyCode(true);其中$session[$name]記錄了驗證碼的使用次數。
發現問題了,我設置了testLimit這個參數等於1。並且,登錄表單還打開了ajax驗證以及提交前驗證功能。 this
知道問題在哪了吧,testLimit表示這個驗證碼只能用一次,而表單的Ajax過程當中驗證了不少次了,致使系統中的驗證碼早就更換了,而頁面中展現的仍是第一次生成的驗證碼圖片。 spa
解決這個問題的辦法就是讓驗證碼在ajax提交的時候不執行$session[$name] = $session[$name] + 1;這一行。
根本緣由找到後就開始解決這個問題。代碼以下:
<?php /** * @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; } } ?>
至此,驗證碼再也不‘飄忽不定’。一切都這麼美好!!!