類別 yii\captcha\CaptchaAction
CaptchaAction 渲染一個 CAPTCHA 圖片。
CaptchaAction 與 yii\captcha\Captcha 和 yii\captcha\CaptchaValidator 一起使用,以提供 CAPTCHA 功能。
透過設定 CaptchaAction 的屬性,您可以自訂產生的 CAPTCHA 圖片的外觀,例如字型顏色、背景顏色等等。
請注意,CaptchaAction 需要 GD2 擴充套件或 ImageMagick PHP 擴充套件。
使用 CAPTCHA 包含以下步驟:
- 覆寫 yii\web\Controller::actions() 並註冊一個 ID 為 'captcha' 的 CaptchaAction 類別的 action。
- 在表單模型中,宣告一個屬性來儲存使用者輸入的驗證碼,並宣告該屬性要通過 'captcha' 驗證器的驗證。
- 在控制器視圖中,於表單中插入一個 yii\captcha\Captcha 小部件。
公開屬性
公開方法
保護方法
方法 | 描述 | 定義於 |
---|---|---|
afterRun() | 此方法在 run() 執行後立即呼叫。 |
yii\base\Action |
beforeRun() | 此方法在 run() 執行前立即呼叫。 |
yii\base\Action |
generateVerifyCode() | 產生新的驗證碼。 | yii\captcha\CaptchaAction |
getSessionKey() | 傳回用於儲存驗證碼的 session 變數名稱。 | yii\captcha\CaptchaAction |
renderImage() | 渲染 CAPTCHA 圖片。 | yii\captcha\CaptchaAction |
renderImageByGD() | 根據程式碼使用 GD 函式庫渲染 CAPTCHA 圖片。 | yii\captcha\CaptchaAction |
renderImageByImagick() | 根據程式碼使用 ImageMagick 函式庫渲染 CAPTCHA 圖片。 | yii\captcha\CaptchaAction |
setHttpHeaders() | 設定圖片回應所需的 HTTP 標頭。 | yii\captcha\CaptchaAction |
常數
常數 | 值 | 描述 | 定義於 |
---|---|---|---|
REFRESH_GET_VAR | 'refresh' | 指示是否應重新產生 CAPTCHA 圖片的 GET 參數名稱。 | yii\captcha\CaptchaAction |
屬性詳細資訊
固定的驗證碼。當設定此屬性時,getVerifyCode() 將始終傳回此屬性的值。這主要用於自動化測試,在自動化測試中,我們希望每次執行測試時都能夠重現相同的驗證碼。如果未設定,則表示驗證碼將隨機產生。
要使用的渲染函式庫。目前僅支援 'gd' 和 'imagick'。如果未設定,將自動判斷函式庫。
同一個 CAPTCHA 應該顯示多少次。預設值為 3。小於或等於 0 的值表示測試次數無限制 (自版本 1.1.2 起可用)。
方法詳細資訊
定義於: yii\base\Component::__call()
呼叫未定義為類別方法的具名方法。
此方法將檢查是否有任何附加的行為具有具名方法,如果有的話,將執行該方法。
請勿直接呼叫此方法,因為它是 PHP magic method,當呼叫未知的方法時,它會被隱含地呼叫。
public mixed __call ( $name, $params ) | ||
$name | string |
方法名稱 |
$params | array |
方法參數 |
return | mixed |
方法的傳回值 |
---|---|---|
throws | yii\base\UnknownMethodException |
當呼叫未知方法時 |
public function __call($name, $params)
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
public void __clone ( ) |
public function __clone()
{
$this->_events = [];
$this->_eventWildcards = [];
$this->_behaviors = null;
}
定義於: yii\base\Action::__construct()
建構子。
public void __construct ( $id, $controller, $config = [] ) | ||
$id | string |
$id |
$controller | 此 action 的 ID |
擁有此 action 的控制器 |
yii\base\Controller | array |
$config |
public function __construct($id, $controller, $config = [])
{
$this->id = $id;
$this->controller = $controller;
parent::__construct($config);
}
傳回元件屬性的值。
定義於: yii\base\Component::__get()
- 此方法將依以下順序檢查並採取相應的動作:
- 由 getter 定義的屬性:傳回 getter 結果
行為的屬性:傳回行為屬性值
請勿直接呼叫此方法,因為它是 PHP magic method,當執行 $value = $component->property;
時,它會被隱含地呼叫。
另請參閱 __set()。 | ||
$name | string |
public mixed __get ( $name ) |
return | mixed |
屬性名稱 |
---|---|---|
throws | 屬性值或行為的屬性值 |
yii\base\UnknownPropertyException |
throws | 如果未定義屬性 |
yii\base\InvalidCallException |
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
// read property, e.g. getName()
return $this->$getter();
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name;
}
}
if (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
檢查屬性是否已設定,即已定義且非 null。
定義於: yii\base\Component::__get()
- 定義於: yii\base\Component::__isset()
- 由 setter 定義的屬性:傳回屬性是否已設定
- 行為的屬性:傳回屬性是否已設定
對於不存在的屬性,傳回 false
請勿直接呼叫此方法,因為它是 PHP magic method,當執行 isset($component->property)
時,它會被隱含地呼叫。
另請參閱 https://php.dev.org.tw/manual/en/function.isset.php。 | ||
$name | string | |
return | boolean |
屬性名稱或事件名稱 |
---|
public function __isset($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter() !== null;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name !== null;
}
}
return false;
}
設定元件屬性的值。
定義於: yii\base\Component::__get()
- 定義於: yii\base\Component::__set()
- 由 setter 定義的屬性:設定屬性值
- 格式為 "on xyz" 的事件:將處理常式附加到事件 "xyz"
- 格式為 "as xyz" 的行為:附加名為 "xyz" 的行為
行為的屬性:設定行為屬性值
請勿直接呼叫此方法,因為它是 PHP magic method,當執行 $component->property = $value;
時,它會被隱含地呼叫。
另請參閱 __get()。 | ||
$name | string | |
$value | mixed |
屬性值 |
throws | 屬性值或行為的屬性值 |
yii\base\UnknownPropertyException |
---|---|---|
throws | 如果未定義屬性 |
如果屬性為唯讀。 |
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
// set property
$this->$setter($value);
return;
} elseif (strncmp($name, 'on ', 3) === 0) {
// on event: attach event handler
$this->on(trim(substr($name, 3)), $value);
return;
} elseif (strncmp($name, 'as ', 3) === 0) {
// as behavior: attach behavior
$name = trim(substr($name, 3));
$this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = $value;
return;
}
}
if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::__unset()
將元件屬性設定為 null。
定義於: yii\base\Component::__get()
- 由 setter 定義的屬性:將屬性值設定為 null
- 行為的屬性:將屬性值設定為 null
請勿直接呼叫此方法,因為它是 PHP magic method,當執行 unset($component->property)
時,它會被隱含地呼叫。
public void __unset ( $name ) | ||
$name | string |
public mixed __get ( $name ) |
throws | 如果未定義屬性 |
如果屬性為唯讀。 |
---|
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter(null);
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = null;
return;
}
}
throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
}
protected void afterRun ( ) |
protected function afterRun()
{
}
定義於: yii\base\Component::attachBehavior()
將行為附加到此元件。
此方法將根據給定的組態建立行為物件。之後,將透過呼叫 yii\base\Behavior::attach() 方法將行為物件附加到此元件。
另請參閱 detachBehavior()。
public yii\base\Behavior attachBehavior ( $name, $behavior ) | ||
$name | string |
行為的名稱。 |
$behavior | string|array|yii\base\Behavior |
行為組態。這可以是以下其中之一:
|
return | yii\base\Behavior |
行為物件 |
---|
public function attachBehavior($name, $behavior)
{
$this->ensureBehaviors();
return $this->attachBehaviorInternal($name, $behavior);
}
定義於: yii\base\Component::attachBehaviors()
將行為列表附加到此元件。
每個行為都以其名稱作為索引,並且應該是一個 yii\base\Behavior 物件、一個指定行為類別的字串,或一個用於建立行為的組態陣列。
另請參閱 attachBehavior()。
public void attachBehaviors ( $behaviors ) | ||
$behaviors | array |
要附加到元件的行為列表 |
public function attachBehaviors($behaviors)
{
$this->ensureBehaviors();
foreach ($behaviors as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
定義於: yii\base\Action::beforeRun()
此方法在 run()
執行前立即呼叫。
您可以覆寫此方法,以便為 action 執行準備工作。如果此方法傳回 false,將會取消 action。
protected boolean beforeRun ( ) | ||
return | boolean |
是否執行 action。 |
---|
protected function beforeRun()
{
return true;
}
Defined in: yii\base\Component::behaviors()
傳回此元件應表現為的行為列表。
子類別可以覆寫此方法來指定它們想要表現的行為。
此方法的傳回值應該是一個行為物件或組態的陣列,並以行為名稱作為索引。行為組態可以是指定行為類別的字串,或是具有以下結構的陣列
'behaviorName' => [
'class' => 'BehaviorClass',
'property1' => 'value1',
'property2' => 'value2',
]
請注意,行為類別必須繼承自 yii\base\Behavior。行為可以使用名稱或匿名方式附加。當名稱用作陣列鍵時,可以使用此名稱,稍後可以使用 getBehavior() 檢索行為,或使用 detachBehavior() 分離行為。匿名行為無法被檢索或分離。
在此方法中宣告的行為將會自動附加到組件(依需求)。
public array behaviors ( ) | ||
return | array |
行為組態。 |
---|
public function behaviors()
{
return [];
}
Defined in: yii\base\Component::canGetProperty()
傳回一個值,指示是否可以讀取屬性。
如果符合以下條件,則屬性可以被讀取
- 類別具有與指定名稱相關聯的 getter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可讀屬性(當
$checkBehaviors
為 true 時)。
另請參閱 canSetProperty()。
public boolean canGetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
public mixed __get ( $name ) |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否可以被讀取 |
---|
public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::canSetProperty()
傳回一個值,指示是否可以設定屬性。
如果符合以下條件,則屬性可以被寫入
- 類別具有與指定名稱相關聯的 setter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可寫屬性(當
$checkBehaviors
為 true 時)。
另請參閱 canGetProperty()。
public boolean canSetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
public mixed __get ( $name ) |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否可以被寫入 |
---|
public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
::class
。
Defined in: yii\base\BaseObject::className()
傳回此類別的完整限定名稱。
public static string className ( ) | ||
return | string |
此類別的完整限定名稱。 |
---|
public static function className()
{
return get_called_class();
}
public yii\base\Behavior|null detachBehavior ( $name ) | ||
$name | string |
行為的名稱。 |
return | yii\base\Behavior|null |
已分離的行為。如果行為不存在,則為 Null。 |
---|
public function detachBehavior($name)
{
$this->ensureBehaviors();
if (isset($this->_behaviors[$name])) {
$behavior = $this->_behaviors[$name];
unset($this->_behaviors[$name]);
$behavior->detach();
return $behavior;
}
return null;
}
Defined in: yii\base\Component::detachBehaviors()
從元件中分離所有行為。
public void detachBehaviors ( ) |
public function detachBehaviors()
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $name => $behavior) {
$this->detachBehavior($name);
}
}
Defined in: yii\base\Component::ensureBehaviors()
確保在 behaviors() 中宣告的行為已附加到此元件。
public void ensureBehaviors ( ) |
public function ensureBehaviors()
{
if ($this->_behaviors === null) {
$this->_behaviors = [];
foreach ($this->behaviors() as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
}
產生可用於客戶端驗證的雜湊碼。
public string generateValidationHash ( $code ) | ||
$code | string |
驗證碼 |
return | string |
從驗證碼產生的雜湊碼 |
---|
public function generateValidationHash($code)
{
for ($h = 0, $i = strlen($code) - 1; $i >= 0; --$i) {
$h += ord($code[$i]) << $i;
}
return $h;
}
產生新的驗證碼。
protected string generateVerifyCode ( ) | ||
return | string |
產生的驗證碼 |
---|
protected function generateVerifyCode()
{
if ($this->minLength > $this->maxLength) {
$this->maxLength = $this->minLength;
}
if ($this->minLength < 3) {
$this->minLength = 3;
}
if ($this->maxLength > 20) {
$this->maxLength = 20;
}
$length = random_int($this->minLength, $this->maxLength);
$letters = 'bcdfghjklmnpqrstvwxyz';
$vowels = 'aeiou';
$code = '';
for ($i = 0; $i < $length; ++$i) {
if ($i % 2 && random_int(0, 10) > 2 || !($i % 2) && random_int(0, 10) > 9) {
$code .= $vowels[random_int(0, 4)];
} else {
$code .= $letters[random_int(0, 20)];
}
}
return $code;
}
Defined in: yii\base\Component::getBehavior()
傳回具名的行為物件。
public yii\base\Behavior|null getBehavior ( $name ) | ||
$name | string |
行為名稱 |
return | yii\base\Behavior|null |
行為物件,如果行為不存在,則為 null |
---|
public function getBehavior($name)
{
$this->ensureBehaviors();
return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
}
Defined in: yii\base\Component::getBehaviors()
傳回附加到此元件的所有行為。
public yii\base\Behavior[] getBehaviors ( ) | ||
return | yii\base\Behavior[] |
附加到此組件的行為列表 |
---|
public function getBehaviors()
{
$this->ensureBehaviors();
return $this->_behaviors;
}
傳回用於儲存驗證碼的 session 變數名稱。
protected string getSessionKey ( ) | ||
return | string |
Session 變數名稱 |
---|
protected function getSessionKey()
{
return '__captcha/' . $this->getUniqueId();
}
Defined in: yii\base\Action::getUniqueId()
傳回此 action 在整個應用程式中的唯一 ID。
public string getUniqueId ( ) | ||
return | string |
此 action 在整個應用程式中的唯一 ID。 |
---|
public function getUniqueId()
{
return $this->controller->getUniqueId() . '/' . $this->id;
}
取得驗證碼。
public string getVerifyCode ( $regenerate = false ) | ||
$regenerate | boolean |
是否應重新產生驗證碼。 |
return | string |
驗證碼。 |
---|
public function getVerifyCode($regenerate = false)
{
if ($this->fixedVerifyCode !== null) {
return $this->fixedVerifyCode;
}
$session = Yii::$app->getSession();
$session->open();
$name = $this->getSessionKey();
if ($session[$name] === null || $regenerate) {
$session[$name] = $this->generateVerifyCode();
$session[$name . 'count'] = 1;
}
return $session[$name];
}
Defined in: yii\base\Component::hasEventHandlers()
傳回一個值,指示是否有名稱事件的任何處理常式。
public boolean hasEventHandlers ( $name ) | ||
$name | string |
事件名稱 |
return | boolean |
是否已附加任何處理常式到事件。 |
---|
public function hasEventHandlers($name)
{
$this->ensureBehaviors();
if (!empty($this->_events[$name])) {
return true;
}
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
return true;
}
}
return Event::hasHandlers($this, $name);
}
Defined in: yii\base\Component::hasMethod()
傳回一個值,指示是否已定義方法。
如果符合以下條件,則定義了方法
- 類別具有具有指定名稱的方法
- 附加的行為具有給定名稱的方法(當
$checkBehaviors
為 true 時)。
public boolean hasMethod ( $name, $checkBehaviors = true ) | ||
$name | string |
public mixed __get ( $name ) |
$checkBehaviors | boolean |
是否將行為的方法視為此組件的方法 |
return | boolean |
方法是否已定義 |
---|
public function hasMethod($name, $checkBehaviors = true)
{
if (method_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->hasMethod($name)) {
return true;
}
}
}
return false;
}
Defined in: yii\base\Component::hasProperty()
傳回一個值,指示是否已為此元件定義屬性。
如果符合以下條件,則定義了屬性
- 類別具有與指定名稱相關聯的 getter 或 setter 方法(在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數(當
$checkVars
為 true 時); - 附加的行為具有給定名稱的屬性(當
$checkBehaviors
為 true 時)。
另請參閱
public boolean hasProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
public mixed __get ( $name ) |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否已定義 |
---|
public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
{
return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
}
初始化 action。
public void init ( ) | ||
throws | yii\base\InvalidConfigException |
如果字型檔案不存在。 |
---|
public function init()
{
$this->fontFile = Yii::getAlias($this->fontFile);
if (!is_file($this->fontFile)) {
throw new InvalidConfigException("The font file does not exist: {$this->fontFile}");
}
}
Defined in: yii\base\Component::off()
從此元件中分離現有的事件處理常式。
此方法與 on() 相反。
注意:如果為事件名稱傳遞了萬用字元模式,則只會移除使用此萬用字元註冊的處理常式,而使用與此萬用字元匹配的純名稱註冊的處理常式將會保留。
另請參閱 on()。
public boolean off ( $name, $handler = null ) | ||
$name | string |
事件名稱 |
$handler | callable|null |
要移除的事件處理常式。如果為 null,則會移除附加到具名事件的所有處理常式。 |
return | boolean |
如果找到並分離處理常式 |
---|
public function off($name, $handler = null)
{
$this->ensureBehaviors();
if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
return false;
}
if ($handler === null) {
unset($this->_events[$name], $this->_eventWildcards[$name]);
return true;
}
$removed = false;
// plain event names
if (isset($this->_events[$name])) {
foreach ($this->_events[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_events[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_events[$name] = array_values($this->_events[$name]);
return true;
}
}
// wildcard event names
if (isset($this->_eventWildcards[$name])) {
foreach ($this->_eventWildcards[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_eventWildcards[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
// remove empty wildcards to save future redundant regex checks:
if (empty($this->_eventWildcards[$name])) {
unset($this->_eventWildcards[$name]);
}
}
}
return $removed;
}
Defined in: yii\base\Component::on()
將事件處理常式附加到事件。
事件處理常式必須是有效的 PHP 回呼。以下是一些範例
function ($event) { ... } // anonymous function
[$object, 'handleClick'] // $object->handleClick()
['Page', 'handleClick'] // Page::handleClick()
'handleClick' // global function handleClick()
事件處理常式必須使用以下簽名定義:
function ($event)
其中 $event
是一個 yii\base\Event 物件,其中包含與事件相關聯的參數。
自 2.0.14 版本起,您可以將事件名稱指定為萬用字元模式
$component->on('event.group.*', function ($event) {
Yii::trace($event->name . ' is triggered.');
});
另請參閱 off()。
public void on ( $name, $handler, $data = null, $append = true ) | ||
$name | string |
事件名稱 |
$handler | callable |
事件處理常式 |
$data | mixed |
當事件觸發時,要傳遞給事件處理常式的資料。當調用事件處理常式時,可以透過 yii\base\Event::$data 存取此資料。 |
$append | boolean |
是否將新的事件處理常式附加到現有處理常式列表的末尾。如果為 false,則新的處理常式將插入到現有處理常式列表的開頭。 |
public function on($name, $handler, $data = null, $append = true)
{
$this->ensureBehaviors();
if (strpos($name, '*') !== false) {
if ($append || empty($this->_eventWildcards[$name])) {
$this->_eventWildcards[$name][] = [$handler, $data];
} else {
array_unshift($this->_eventWildcards[$name], [$handler, $data]);
}
return;
}
if ($append || empty($this->_events[$name])) {
$this->_events[$name][] = [$handler, $data];
} else {
array_unshift($this->_events[$name], [$handler, $data]);
}
}
渲染 CAPTCHA 圖片。
protected string renderImage ( $code ) | ||
$code | string |
驗證碼 |
return | string |
圖片內容 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果 imageLibrary 不支援 |
protected function renderImage($code)
{
if (isset($this->imageLibrary)) {
$imageLibrary = $this->imageLibrary;
} else {
$imageLibrary = Captcha::checkRequirements();
}
if ($imageLibrary === 'gd') {
return $this->renderImageByGD($code);
} elseif ($imageLibrary === 'imagick') {
return $this->renderImageByImagick($code);
}
throw new InvalidConfigException("Defined library '{$imageLibrary}' is not supported");
}
根據程式碼使用 GD 函式庫渲染 CAPTCHA 圖片。
protected string renderImageByGD ( $code ) | ||
$code | string |
驗證碼 |
return | string |
PNG 格式的圖片內容。 |
---|
protected function renderImageByGD($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 - 1, $this->height - 1, $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
);
$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) (random_int(26, 32) * $scale * 0.8);
$angle = random_int(-10, 10);
$letter = $code[$i];
$box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter);
$x = $box[2] + $this->offset;
}
imagecolordeallocate($image, $foreColor);
ob_start();
imagepng($image);
imagedestroy($image);
return ob_get_clean();
}
根據程式碼使用 ImageMagick 函式庫渲染 CAPTCHA 圖片。
protected string renderImageByImagick ( $code ) | ||
$code | string |
驗證碼 |
return | string |
PNG 格式的圖片內容。 |
---|
protected function renderImageByImagick($code)
{
$backColor = $this->transparent ? new \ImagickPixel('transparent') : new \ImagickPixel('#' . str_pad(dechex($this->backColor), 6, 0, STR_PAD_LEFT));
$foreColor = new \ImagickPixel('#' . str_pad(dechex($this->foreColor), 6, 0, STR_PAD_LEFT));
$image = new \Imagick();
$image->newImage($this->width, $this->height, $backColor);
$draw = new \ImagickDraw();
$draw->setFont($this->fontFile);
$draw->setFontSize(30);
$fontMetrics = $image->queryFontMetrics($draw, $code);
$length = strlen($code);
$w = (int) $fontMetrics['textWidth'] - 8 + $this->offset * ($length - 1);
$h = (int) $fontMetrics['textHeight'] - 8;
$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) {
$draw = new \ImagickDraw();
$draw->setFont($this->fontFile);
$draw->setFontSize((int) (random_int(26, 32) * $scale * 0.8));
$draw->setFillColor($foreColor);
$image->annotateImage($draw, $x, $y, random_int(-10, 10), $code[$i]);
$fontMetrics = $image->queryFontMetrics($draw, $code[$i]);
$x += (int) $fontMetrics['textWidth'] + $this->offset;
}
$image->setImageFormat('png');
return $image->getImageBlob();
}
執行 action。
public void run ( ) |
public function run()
{
if (Yii::$app->request->getQueryParam(self::REFRESH_GET_VAR) !== null) {
// AJAX request for regenerating code
$code = $this->getVerifyCode(true);
Yii::$app->response->format = Response::FORMAT_JSON;
return [
'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' => Url::to([$this->id, 'v' => uniqid('', true)]),
];
}
$this->setHttpHeaders();
Yii::$app->response->format = Response::FORMAT_RAW;
return $this->renderImage($this->getVerifyCode());
}
public mixed runWithParams ( $params ) | ||
$params | array |
要綁定到 action 的 run() 方法的參數。 |
return | mixed |
action 的結果 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果 action 類別沒有 run() 方法 |
public function runWithParams($params)
{
if (!method_exists($this, 'run')) {
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
}
$args = $this->controller->bindActionParams($this, $params);
Yii::debug('Running action: ' . get_class($this) . '::run(), invoked by ' . get_class($this->controller), __METHOD__);
if (Yii::$app->requestedParams === null) {
Yii::$app->requestedParams = $args;
}
if ($this->beforeRun()) {
$result = call_user_func_array([$this, 'run'], $args);
$this->afterRun();
return $result;
}
return null;
}
設定圖片回應所需的 HTTP 標頭。
protected void setHttpHeaders ( ) |
protected function setHttpHeaders()
{
Yii::$app->getResponse()->getHeaders()
->set('Pragma', 'public')
->set('Expires', '0')
->set('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->set('Content-Transfer-Encoding', 'binary')
->set('Content-type', 'image/png');
}
public void trigger ( $name, yii\base\Event $event = null ) | ||
$name | string |
事件名稱 |
$event | yii\base\Event|null |
事件實例。如果未設定,將會建立預設的 yii\base\Event 物件。 |
public function trigger($name, Event $event = null)
{
$this->ensureBehaviors();
$eventHandlers = [];
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (StringHelper::matchWildcard($wildcard, $name)) {
$eventHandlers[] = $handlers;
}
}
if (!empty($this->_events[$name])) {
$eventHandlers[] = $this->_events[$name];
}
if (!empty($eventHandlers)) {
$eventHandlers = call_user_func_array('array_merge', $eventHandlers);
if ($event === null) {
$event = new Event();
}
if ($event->sender === null) {
$event->sender = $this;
}
$event->handled = false;
$event->name = $name;
foreach ($eventHandlers as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
// stop further handling if the event is handled
if ($event->handled) {
return;
}
}
}
// invoke class-level attached handlers
Event::trigger($this, $name, $event);
}
驗證輸入是否與產生的程式碼相符。
public boolean validate ( $input, $caseSensitive ) | ||
$input | string |
使用者輸入 |
$caseSensitive | boolean |
比較是否應該區分大小寫 |
return | boolean |
輸入是否有效 |
---|
public function validate($input, $caseSensitive)
{
$code = $this->getVerifyCode();
$valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0;
$session = Yii::$app->getSession();
$session->open();
$name = $this->getSessionKey() . 'count';
$session[$name] += 1;
if ($valid || $session[$name] > $this->testLimit && $this->testLimit > 0) {
$this->getVerifyCode(true);
}
return $valid;
}
Signup or Login in order to comment.