包 | system.web.widgets.captcha |
---|---|
继承 | class CCaptchaAction » CAction » CComponent |
实现 | IAction |
源自 | 1.0 |
版本 | $Id: CCaptchaAction.php 3515 2011-12-28 12:29:24Z mdomba $ |
源码 |
CCaptchaAction用于生成验证码图片。
CCaptchaAction需要CCaptcha和CCaptchaValidator 配合使用来生成所需的验证码CAPTCHA图片。
你必须配置CCaptchaAction的属性 来定制所需的验证码样式。
注意,CCaptchaAction要求开启PHP的GD2拓展。
使用验证码包含以下步骤:
CCaptchaAction需要CCaptcha和CCaptchaValidator 配合使用来生成所需的验证码CAPTCHA图片。
你必须配置CCaptchaAction的属性 来定制所需的验证码样式。
注意,CCaptchaAction要求开启PHP的GD2拓展。
使用验证码包含以下步骤:
- 重写CController::actions()并且注册一个继承于CCaptchaAction类ID为‘captcha’的方法。
- 在form模型中,声明一个变量用于存储用户输入的验证码并且 用’captcha‘验证这个变量。
- 在控制器的视图表单中插入一个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 |
公共方法
受保护方法
方法 | 描述 | 定义在 |
---|---|---|
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 % 2 && mt_rand(0,10) > 2 || !($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;
}
验证用户输入是否匹配生成的验证码。