dd

CCaptchaAction


system.web.widgets.captcha
继承 class CCaptchaAction » CAction » CComponent
实现 IAction
源自 1.0
版本 $Id: CCaptchaAction.php 3515 2011-12-28 12:29:24Z mdomba $
源码
CCaptchaAction用于生成验证码图片。

CCaptchaAction需要CCaptchaCCaptchaValidator 配合使用来生成所需的验证码CAPTCHA图片。

你必须配置CCaptchaAction的属性 来定制所需的验证码样式。

注意,CCaptchaAction要求开启PHP的GD2拓展。

使用验证码包含以下步骤:
  1. 重写CController::actions()并且注册一个继承于CCaptchaAction类ID为‘captcha’的方法。
  2. 在form模型中,声明一个变量用于存储用户输入的验证码并且 用’captcha‘验证这个变量。
  3. 在控制器的视图表单中插入一个CCaptcha组件。

公共属性

属性 类型 描述 定义在
backColor integer 背景颜色。如,0x55FF00。 默认为0xFFFFFF,意味着白色。 CCaptchaAction
controller CController 拥有这个动作的控制器。 CAction
fixedVerifyCode string 固定的验证码。设置这个属性以后, getVerifyCode方法会一直返回这个值。 当我们在自动测试中想每次返回 相同的验证码值时会用到。 默认是null,这意味着将随机生成验证码。 CCaptchaAction
fontFile string TrueType文字文件。默认为Duality. CCaptchaAction
foreColor integer 字体颜色。如,0x55FF00。默认是0x2040A0(蓝色)。 CCaptchaAction
height integer 验证码图片高度。默认为50。 CCaptchaAction
id string 动作的ID。 CAction
maxLength integer 生成字符串的最大长度。默认是7。 CCaptchaAction
minLength integer 生成字符串的最小长度。默认是6。 CCaptchaAction
offset integer 字符间偏移量。默认是-2。 你可以调整这个值来增加或减少验证码的可读性。 CCaptchaAction
padding integer 文字周边填充大小。默认为2。 CCaptchaAction
testLimit integer 相同验证码出现的次数。默认为3。 小于等于0的值意味着不限制(自版本1. CCaptchaAction
transparent boolean 是否使用透明背景。默认为false。 CCaptchaAction
verifyCode string 获取验证码。 CCaptchaAction
width integer 验证码图片宽度。默认为120。 CCaptchaAction

受保护属性

属性 类型 描述 定义在
sessionKey string 返回存储验证码的会话变量名。 CCaptchaAction

公共方法

方法 描述 定义在
__call() 如果类中没有调的方法名,则调用这个方法。 CComponent
__construct() 构造方法。 CAction
__get() 返回一个属性值、一个事件处理程序列表或一个行为名称。 CComponent
__isset() 检查一个属性是否为null。 CComponent
__set() 设置一个组件的属性值。 CComponent
__unset() 设置一个组件的属性为null。 CComponent
asa() 返回这个名字的行为对象。 CComponent
attachBehavior() 附加一个行为到组件。 CComponent
attachBehaviors() 附加一个行为列表到组件。 CComponent
attachEventHandler() 为事件附加一个事件处理程序。 CComponent
canGetProperty() 确定属性是否可读。 CComponent
canSetProperty() 确定属性是否可写。 CComponent
detachBehavior() 从组件中分离一个行为。 CComponent
detachBehaviors() 从组件中分离所有行为。 CComponent
detachEventHandler() 分离一个存在的事件处理程序。 CComponent
disableBehavior() 禁用一个附加行为。 CComponent
disableBehaviors() 禁用组件附加的所有行为。 CComponent
enableBehavior() 启用一个附加行为。 CComponent
enableBehaviors() 启用组件附加的所有行为。 CComponent
evaluateExpression() 计算一个PHP表达式,或根据组件上下文执行回调。 CComponent
generateValidationHash() 生成可用于客户端的哈希值。 CCaptchaAction
getController() 返回拥有这个动作的控制器。 CAction
getEventHandlers() 返回一个事件的附加处理程序列表。 CComponent
getId() 返回动作的ID。 CAction
getVerifyCode() 获取验证码。 CCaptchaAction
hasEvent() 确定一个事件是否定义。 CComponent
hasEventHandler() 检查事件是否有附加的处理程序。 CComponent
hasProperty() 确定属性是否被定义。 CComponent
raiseEvent() 发起一个事件。 CComponent
run() 执行动作。 CCaptchaAction
runWithParams() 运行带有请求参数的对象。 CAction
validate() 验证用户输入是否匹配生成的验证码。 CCaptchaAction

受保护方法

方法 描述 定义在
generateVerifyCode() 生成一个新验证码。 CCaptchaAction
getSessionKey() 返回存储验证码的会话变量名。 CCaptchaAction
renderImage() 渲染基于验证码值的验证码图片。 CCaptchaAction
runWithParamsInternal() 执行一个带有命名参数的对象的方法。 CAction

属性详细

backColor 属性
public integer $backColor;

背景颜色。如,0x55FF00。 默认为0xFFFFFF,意味着白色。

fixedVerifyCode 属性 (可用自 v1.1.4)
public string $fixedVerifyCode;

固定的验证码。设置这个属性以后, getVerifyCode方法会一直返回这个值。 当我们在自动测试中想每次返回 相同的验证码值时会用到。 默认是null,这意味着将随机生成验证码。

fontFile 属性
public string $fontFile;

TrueType文字文件。默认为Duality.ttf,由Yii 发行版中提供。

foreColor 属性
public integer $foreColor;

字体颜色。如,0x55FF00。默认是0x2040A0(蓝色)。

height 属性
public integer $height;

验证码图片高度。默认为50。

maxLength 属性
public integer $maxLength;

生成字符串的最大长度。默认是7。

minLength 属性
public integer $minLength;

生成字符串的最小长度。默认是6。

offset 属性 (可用自 v1.1.7)
public integer $offset;

字符间偏移量。默认是-2。 你可以调整这个值来增加或减少验证码的可读性。

padding 属性
public integer $padding;

文字周边填充大小。默认为2。

sessionKey 属性 只读
protected string getSessionKey()

返回存储验证码的会话变量名。

testLimit 属性
public integer $testLimit;

相同验证码出现的次数。默认为3。 小于等于0的值意味着不限制(自版本1.1.2开始支持)。

transparent 属性
public boolean $transparent;

是否使用透明背景。默认为false。

verifyCode 属性 只读
public string getVerifyCode(boolean $regenerate=false)

获取验证码。

width 属性
public integer $width;

验证码图片宽度。默认为120。

方法详细

generateValidationHash() 方法 (可用自 v1.1.7)
public string generateValidationHash(string $code)
$code string 验证码
{return} string 由验证码生成的一个哈希值
public function generateValidationHash($code)
{
    for(
$h=0,$i=strlen($code)-1;$i>=0;--$i)
        
$h+=ord($code[$i]);
    return 
$h;
}

生成可用于客户端的哈希值。

generateVerifyCode() 方法
protected string generateVerifyCode()
{return} string 生成的验证码。
protected function generateVerifyCode()
{
    if(
$this->minLength 3)
        
$this->minLength 3;
    if(
$this->maxLength 20)
        
$this->maxLength 20;
    if(
$this->minLength $this->maxLength)
        
$this->maxLength $this->minLength;
    
$length mt_rand($this->minLength,$this->maxLength);

    
$letters 'bcdfghjklmnpqrstvwxyz';
    
$vowels 'aeiou';
    
$code '';
    for(
$i 0$i $length; ++$i)
    {
        if(
$i && mt_rand(0,10) > || !($i 2) && mt_rand(0,10) > 9)
            
$code.=$vowels[mt_rand(0,4)];
        else
            
$code.=$letters[mt_rand(0,20)];
    }

    return 
$code;
}

生成一个新验证码。

getSessionKey() 方法
protected string getSessionKey()
{return} string 会话变量名称
protected function getSessionKey()
{
    return 
self::SESSION_VAR_PREFIX Yii::app()->getId() . '.' $this->getController()->getUniqueId() . '.' $this->getId();
}

返回存储验证码的会话变量名。

getVerifyCode() 方法
public string getVerifyCode(boolean $regenerate=false)
$regenerate boolean 验证码是否重新生成。
{return} string 验证码。
public function getVerifyCode($regenerate=false)
{
    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];
}

获取验证码。

renderImage() 方法
protected string renderImage(string $code)
$code string 验证码值
{return} string 图片内容
protected function renderImage($code)
{
    
$image imagecreatetruecolor($this->width,$this->height);

    
$backColor imagecolorallocate($image,
            (int)(
$this->backColor 0x1000000 0x10000),
            (int)(
$this->backColor 0x10000 0x100),
            
$this->backColor 0x100);
    
imagefilledrectangle($image,0,0,$this->width,$this->height,$backColor);
    
imagecolordeallocate($image,$backColor);

    if(
$this->transparent)
        
imagecolortransparent($image,$backColor);

    
$foreColor imagecolorallocate($image,
            (int)(
$this->foreColor 0x1000000 0x10000),
            (int)(
$this->foreColor 0x10000 0x100),
            
$this->foreColor 0x100);

    if(
$this->fontFile === null)
        
$this->fontFile dirname(__FILE__) . '/Duality.ttf';

    
$length strlen($code);
    
$box imagettfbbox(30,0,$this->fontFile,$code);
    
$w $box[4] - $box[0] + $this->offset * ($length 1);
    
$h $box[1] - $box[5];
    
$scale min(($this->width $this->padding 2) / $w,($this->height $this->padding 2) / $h);
    
$x 10;
    
$y round($this->height 27 40);
    for(
$i 0$i $length; ++$i)
    {
        
$fontSize = (int)(rand(26,32) * $scale 0.8);
        
$angle rand(-10,10);
        
$letter $code[$i];
        
$box imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);
        
$x $box[2] + $this->offset;
    }

    
imagecolordeallocate($image,$foreColor);

    
header('Pragma: public');
    
header('Expires: 0');
    
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    
header('Content-Transfer-Encoding: binary');
    
header("Content-type: image/png");
    
imagepng($image);
    
imagedestroy($image);
}

渲染基于验证码值的验证码图片。

run() 方法
public void run()
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());
    
Yii::app()->end();
}

执行动作。

validate() 方法
public boolean validate(string $input, boolean $caseSensitive)
$input string 用户输入值
$caseSensitive boolean 匹配时是否区分大小写
{return} boolean 输入是否有效
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';
    
$session[$name] = $session[$name] + 1;
    if(
$session[$name] > $this->testLimit && $this->testLimit 0)
        
$this->getVerifyCode(true);
    return 
$valid;
}

验证用户输入是否匹配生成的验证码。