原因:
每次刷新頁面的時候都會調(diào)用CCaptcha這個widget的run方法來運(yùn)行這個助手:
/**
?*?Renders?the?widget.
?*/
public?function?run()
{
????if(self::checkRequirements())
????{
????????$this->renderImage();???//生成驗證碼圖片
????????$this->registerClientScript();
????}
????else
????????throw?new?CException(Yii::t('yii','GD?and?FreeType?PHP?extensions?are?required.'));
}
/**
?*?Renders?the?CAPTCHA?image.
?*/
protected?function?renderImage()
{
????if(!isset($this->imageOptions['id']))
????????$this->imageOptions['id']=$this->getId();
???//生成驗證碼圖片鏈接src地址,這個是生成圖片的關(guān)鍵,指向action為?$captchaAction='captcha'的方法,即調(diào) 用CCaptchaAction這個方法來生成驗證碼圖片
????$url=$this->getController()->createUrl($this->captchaAction,array('v'=>uniqid()));
????$alt=isset($this->imageOptions['alt'])?$this->imageOptions['alt']:'';
????echo?CHtml::image($url,$alt,$this->imageOptions);
}
CCaptchaAction中的執(zhí)行流程:
/**
?*?Runs?the?action.
?*/
public?function?run()
{
????if(isset($_GET[self::REFRESH_GET_VAR]))??//?AJAX?request?for?regenerating?code
????{
????????$code=$this->getVerifyCode(true);
????????echo?CJSON::encode(array(
????????????'hash1'=>$this->generateValidationHash($code),
????????????'hash2'=>$this->generateValidationHash(strtolower($code)),
????????????//?we?add?a?random?'v'?parameter?so?that?FireFox?can?refresh?the?image
????????????//?when?src?attribute?of?image?tag?is?changed
????????????'url'=>$this->getController()->createUrl($this->getId(),array('v'?=>?uniqid())),
????????));
????}
????else
????????$this->renderImage($this->getVerifyCode());??//刷新頁面時會調(diào)用這個,問題就出現(xiàn)在這,他調(diào)用 這個方法的時候沒有傳遞參數(shù)true
????Yii::app()->end();
}
/**
?*?Gets?the?verification?code.
?*?@param?boolean?$regenerate?whether?the?verification?code?should?be?regenerated.
?*?@return?string?the?verification?code.
?*/
public?function?getVerifyCode($regenerate=false)?//從這個參數(shù)可以看出?如果$regenerate為true,則會 重新生成驗證碼圖片
{
????if($this->fixedVerifyCode?!==?null)
????????return?$this->fixedVerifyCode;
????$session?=?Yii::app()->session;
????$session->open();
????$name?=?$this->getSessionKey();
????if($session[$name]?===?null?||?$regenerate)
????{
????????$session[$name]?=?$this->generateVerifyCode();
????????$session[$name?.?'count']?=?1;
????}
????return?$session[$name];
}? 解決辦法: 一:根據(jù)getVerifyCode這個方法中的這段代碼來修改,這段代碼是用于驗證的,如果設(shè)定了fixedVerifyCode,則每次 生成時都會生成一個固定的驗證碼,我們所要做的是把這個固定的變成動態(tài)的。?? ? if($this->fixedVerifyCode?!==?null)? ????????return?$this->fixedVerifyCode; 修改控制器中生成驗證碼的配置: /** ?*?Declares?class-based?actions. ?*/ public?function?actions() { ????return?array( ????????//?captcha?action?renders?the?CAPTCHA?image?displayed?on?the?register?page ????????'captcha'=>array( ????????????'class'=>'CCaptchaAction','fixedVerifyCode'?=>?substr(md5(time()),0,4),?'foreColor'?=>?0x55FF00, ????????????'testLimit'?=>?0,??//不限制相同驗證碼出現(xiàn)的次數(shù) ????????????'offset'?=>?5, ????????????'minLength'?=>?4, ????????????'maxLength'?=>?4, ????????????'transparent'?=>?true, ????????), ????); }? 二、繼承CCaptchaAction這個類,修改?run()方法中的?$this->renderImage($this->getVerifyCode())這句為 $this->renderImage($this->getVerifyCode(true)),其他不變 缺點(diǎn):這種方法在CActiveForm開啟enableClientValidation=true時,總是報驗證碼不正確, enableAjaxValidation開啟沒事,待解決。。。 代碼如下: 繼承的類DCCaptchaAction.php
對應(yīng)修改生成驗證碼的controller如下: