0 關注者

類別 yii\behaviors\AttributeTypecastBehavior

繼承yii\behaviors\AttributeTypecastBehavior » yii\base\Behavior » yii\base\BaseObject
實作yii\base\Configurable
自版本起可用2.0.10
原始碼 https://github.com/yiisoft/yii2/blob/master/framework/behaviors/AttributeTypecastBehavior.php

AttributeTypecastBehavior 提供了自動模型屬性類型轉換的能力。

當使用 ActiveRecord 於無結構描述資料庫(如 MongoDB 或 Redis)時,此行為非常有用。 它也可能對常規 yii\db\ActiveRecord 甚至 yii\base\Model 派上用場,允許在模型驗證後維護嚴格的屬性類型。

此行為應附加到 yii\base\Modelyii\db\BaseActiveRecord 的後代。

您應該通過 $attributeTypes 指定確切的屬性類型。

例如

use yii\behaviors\AttributeTypecastBehavior;

class Item extends \yii\db\ActiveRecord
{
    public function behaviors()
    {
        return [
            'typecast' => [
                'class' => AttributeTypecastBehavior::class,
                'attributeTypes' => [
                    'amount' => AttributeTypecastBehavior::TYPE_INTEGER,
                    'price' => AttributeTypecastBehavior::TYPE_FLOAT,
                    'is_active' => AttributeTypecastBehavior::TYPE_BOOLEAN,
                ],
                'typecastAfterValidate' => true,
                'typecastBeforeSave' => false,
                'typecastAfterFind' => false,
            ],
        ];
    }

    // ...
}

提示:您可以將 $attributeTypes 留空 - 在這種情況下,它的值將根據所有者的驗證規則自動檢測。 以下範例將自動建立與上述範例中配置的相同的 $attributeTypes

use yii\behaviors\AttributeTypecastBehavior;

class Item extends \yii\db\ActiveRecord
{

    public function rules()
    {
        return [
            ['amount', 'integer'],
            ['price', 'number'],
            ['is_active', 'boolean'],
        ];
    }

    public function behaviors()
    {
        return [
            'typecast' => [
                'class' => AttributeTypecastBehavior::class,
                // 'attributeTypes' will be composed automatically according to `rules()`
            ],
        ];
    }

    // ...
}

此行為允許在以下情況自動進行屬性類型轉換

  • 模型成功驗證後
  • 模型儲存前(插入或更新)
  • 模型查找後(通過查詢找到或刷新)

您可以使用欄位 $typecastAfterValidate$typecastBeforeSave$typecastAfterFind 控制特定情況下的自動類型轉換。 預設情況下,類型轉換將僅在模型驗證後執行。

注意:您可以隨時通過調用 typecastAttributes() 方法手動觸發屬性類型轉換

$model = new Item();
$model->price = '38.5';
$model->is_active = 1;
$model->typecastAttributes();

公共屬性

隱藏繼承的屬性

屬性 類型 描述 定義於
$attributeTypes array|null 屬性類型轉換映射,格式為:attributeName => type。 yii\behaviors\AttributeTypecastBehavior
$owner yii\base\Model|yii\db\BaseActiveRecord 此行為的所有者。 yii\behaviors\AttributeTypecastBehavior
$skipOnNull boolean 是否跳過 null 值的類型轉換。 yii\behaviors\AttributeTypecastBehavior
$typecastAfterFind boolean 是否在從資料庫檢索所有者模型資料後(在查找或刷新後)執行類型轉換。 yii\behaviors\AttributeTypecastBehavior
$typecastAfterSave boolean 是否在儲存所有者模型後(插入或更新)執行類型轉換。 yii\behaviors\AttributeTypecastBehavior
$typecastAfterValidate boolean 是否在所有者模型驗證後執行類型轉換。 yii\behaviors\AttributeTypecastBehavior
$typecastBeforeSave boolean 是否在儲存所有者模型之前(插入或更新)執行類型轉換。 yii\behaviors\AttributeTypecastBehavior

公共方法

隱藏繼承的方法

方法 描述 定義於
__call() 調用指定的非類別方法。 yii\base\BaseObject
__construct() 建構子。 yii\base\BaseObject
__get() 傳回物件屬性的值。 yii\base\BaseObject
__isset() 檢查屬性是否已設定,即已定義且不為 null。 yii\base\BaseObject
__set() 設定物件屬性的值。 yii\base\BaseObject
__unset() 將物件屬性設定為 null。 yii\base\BaseObject
afterFind() 處理所有者的 'afterFind' 事件,確保屬性類型轉換。 yii\behaviors\AttributeTypecastBehavior
afterSave() 處理所有者的 'afterInsert' 和 'afterUpdate' 事件,確保屬性類型轉換。 yii\behaviors\AttributeTypecastBehavior
afterValidate() 處理所有者的 'afterValidate' 事件,確保屬性類型轉換。 yii\behaviors\AttributeTypecastBehavior
attach() 將行為物件附加到元件。 yii\behaviors\AttributeTypecastBehavior
beforeSave() 處理所有者的 'beforeInsert' 和 'beforeUpdate' 事件,確保屬性類型轉換。 yii\behaviors\AttributeTypecastBehavior
canGetProperty() 傳回一個值,指示是否可以讀取屬性。 yii\base\BaseObject
canSetProperty() 傳回一個值,指示是否可以設定屬性。 yii\base\BaseObject
className() 傳回此類別的完整限定名稱。 yii\base\BaseObject
clearAutoDetectedAttributeTypes() 清除自動偵測到的 $attributeTypes 值在所有受影響的所有者類別中的內部靜態快取。 yii\behaviors\AttributeTypecastBehavior
detach() 從元件分離行為物件。 yii\base\Behavior
events() 宣告 $owner 的事件的事件處理常式。 yii\behaviors\AttributeTypecastBehavior
hasMethod() 傳回一個值,指示是否已定義方法。 yii\base\BaseObject
hasProperty() 傳回一個值,指示是否已定義屬性。 yii\base\BaseObject
init() 初始化物件。 yii\base\BaseObject
typecastAttributes() 根據 $attributeTypes 轉換所有者屬性的類型。 yii\behaviors\AttributeTypecastBehavior

保護方法

隱藏繼承的方法

方法 描述 定義於
detectAttributeTypes() 從所有者的驗證規則組成 $attributeTypes 的預設值。 yii\behaviors\AttributeTypecastBehavior
resetOldAttributes() 重置指定屬性的舊值。 yii\behaviors\AttributeTypecastBehavior
typecastValue() 將給定值轉換為指定的類型。 yii\behaviors\AttributeTypecastBehavior

常數

隱藏繼承的常數

常數 描述 定義於
TYPE_BOOLEAN 'boolean' yii\behaviors\AttributeTypecastBehavior
TYPE_FLOAT 'float' yii\behaviors\AttributeTypecastBehavior
TYPE_INTEGER 'integer' yii\behaviors\AttributeTypecastBehavior
TYPE_STRING 'string' yii\behaviors\AttributeTypecastBehavior

屬性詳細資料

隱藏繼承的屬性

$attributeTypes 公有屬性

屬性類型轉換映射,格式為:attributeName => type。類型可以透過 PHP 可呼叫函數設定,該函數接受原始值作為參數,並應傳回類型轉換結果。例如:

[
    'amount' => 'integer',
    'price' => 'float',
    'is_active' => 'boolean',
    'date' => function ($value) {
        return ($value instanceof \DateTime) ? $value->getTimestamp(): (int) $value;
    },
]

如果未設定,屬性類型映射將會從擁有者的驗證規則自動組成。

public array|null $attributeTypes null
$owner 公有屬性

此行為的所有者。

$skipOnNull 公有屬性

是否跳過對 null 值進行類型轉換。如果啟用,屬性值等於 null 時將不會進行類型轉換(例如,null 保持為 null),否則將根據 $attributeTypes 中設定的類型進行轉換。

public boolean $skipOnNull true
$typecastAfterFind 公有屬性

是否在從資料庫檢索擁有者模型資料後(在 find 或 refresh 之後)執行類型轉換。可以停用此選項以獲得更好的效能。例如,在使用 yii\db\ActiveRecord 的情況下,find 之後的類型轉換在大多數情況下不會帶來任何好處,因此可以停用。請注意,在此行為附加到模型後,變更此選項值將不會有任何效果。

public boolean $typecastAfterFind false
$typecastAfterSave 公有屬性 (自版本 2.0.14 起可用)

是否在儲存擁有者模型之後(插入或更新)執行類型轉換。可以停用此選項以獲得更好的效能。例如,在使用 yii\db\ActiveRecord 的情況下,save 之後的類型轉換在大多數情況下不會帶來任何好處,因此可以停用。請注意,在此行為附加到模型後,變更此選項值將不會有任何效果。

public boolean $typecastAfterSave false
$typecastAfterValidate 公有屬性

是否在擁有者模型驗證後執行類型轉換。請注意,只有在驗證成功(例如,擁有者模型沒有錯誤)時才會執行類型轉換。請注意,在此行為附加到模型後,變更此選項值將不會有任何效果。

$typecastBeforeSave 公有屬性

是否在儲存擁有者模型之前(插入或更新)執行類型轉換。可以停用此選項以獲得更好的效能。例如,在使用 yii\db\ActiveRecord 的情況下,save 之前的類型轉換在大多數情況下不會帶來任何好處,因此可以停用。請注意,在此行為附加到模型後,變更此選項值將不會有任何效果。

方法詳情

隱藏繼承的方法

__call() 公有方法

定義於: yii\base\BaseObject::__call()

調用指定的非類別方法。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當呼叫未知方法時會被隱式呼叫。

public mixed __call ( $name, $params )
$name string

方法名稱

$params array

方法參數

return mixed

方法傳回值

throws yii\base\UnknownMethodException

當呼叫未知方法時

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() 公有方法

定義於: yii\base\BaseObject::__construct()

建構子。

預設實作執行兩件事

  • 使用給定的設定 $config 初始化物件。
  • 呼叫 init()

如果在子類別中覆寫此方法,建議

  • 建構子的最後一個參數是設定陣列,例如此處的 $config
  • 在建構子的結尾呼叫父類別實作。
public void __construct ( $config = [] )
$config array

將用於初始化物件屬性的名稱-值對

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() 公有方法

定義於: yii\base\BaseObject::__get()

傳回物件屬性的值。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $value = $object->property; 時會被隱式呼叫。

另請參閱 __set()

public mixed __get ( $name )
$name string

屬性名稱

return mixed

屬性值

throws yii\base\UnknownPropertyException

如果屬性未定義

throws yii\base\InvalidCallException

如果屬性為唯寫

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (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);
}

            
__isset() 公有方法

定義於: yii\base\BaseObject::__isset()

檢查屬性是否已設定,即已定義且不為 null。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 isset($object->property) 時會被隱式呼叫。

請注意,如果屬性未定義,將傳回 false。

另請參閱 https://php.dev.org.tw/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

屬性名稱或事件名稱

return boolean

具名屬性是否已設定(非 null)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() 公有方法

定義於: yii\base\BaseObject::__set()

設定物件屬性的值。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $object->property = $value; 時會被隱式呼叫。

另請參閱 __get()

public void __set ( $name, $value )
$name string

屬性名稱或事件名稱

$value mixed

屬性值

throws yii\base\UnknownPropertyException

如果屬性未定義

throws yii\base\InvalidCallException

如果屬性為唯讀

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() 公有方法

定義於: yii\base\BaseObject::__unset()

將物件屬性設定為 null。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 unset($object->property) 時會被隱式呼叫。

請注意,如果屬性未定義,此方法將不會執行任何操作。如果屬性為唯讀,則會擲回例外。

另請參閱 https://php.dev.org.tw/manual/en/function.unset.php

public void __unset ( $name )
$name string

屬性名稱

throws yii\base\InvalidCallException

如果屬性為唯讀。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
afterFind() 公有方法

處理所有者的 'afterFind' 事件,確保屬性類型轉換。

public void afterFind ( $event )
$event yii\base\Event

事件實例。

                public function afterFind($event)
{
    $this->typecastAttributes();
    $this->resetOldAttributes();
}

            
afterSave() 公有方法 (自版本 2.0.14 起可用)

處理所有者的 'afterInsert' 和 'afterUpdate' 事件,確保屬性類型轉換。

public void afterSave ( $event )
$event yii\base\Event

事件實例。

                public function afterSave($event)
{
    $this->typecastAttributes();
}

            
afterValidate() 公有方法

處理所有者的 'afterValidate' 事件,確保屬性類型轉換。

public void afterValidate ( $event )
$event yii\base\Event

事件實例。

                public function afterValidate($event)
{
    if (!$this->owner->hasErrors()) {
        $this->typecastAttributes();
    }
}

            
attach() 公有方法

將行為物件附加到元件。

預設實作將設定 $owner 屬性,並附加 events() 中宣告的事件處理常式。如果您覆寫此方法,請確保呼叫父類別實作。

public void attach ( $owner )
$owner yii\base\Component

要附加此行為的元件。

                public function attach($owner)
{
    parent::attach($owner);
    if ($this->attributeTypes === null) {
        $ownerClass = get_class($this->owner);
        if (!isset(self::$_autoDetectedAttributeTypes[$ownerClass])) {
            self::$_autoDetectedAttributeTypes[$ownerClass] = $this->detectAttributeTypes();
        }
        $this->attributeTypes = self::$_autoDetectedAttributeTypes[$ownerClass];
    }
}

            
beforeSave() 公有方法

處理所有者的 'beforeInsert' 和 'beforeUpdate' 事件,確保屬性類型轉換。

public void beforeSave ( $event )
$event yii\base\Event

事件實例。

                public function beforeSave($event)
{
    $this->typecastAttributes();
}

            
canGetProperty() 公有方法

定義於: yii\base\BaseObject::canGetProperty()

傳回一個值,指示是否可以讀取屬性。

如果屬性可讀,則為:

  • 類別具有與指定名稱相關聯的 getter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canSetProperty()

public boolean canGetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可讀

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() 公有方法

定義於: yii\base\BaseObject::canSetProperty()

傳回一個值,指示是否可以設定屬性。

如果屬性可寫入,則為:

  • 類別具有與指定名稱相關聯的 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canGetProperty()

public boolean canSetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可寫入

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
className() 公有靜態方法
自 2.0.14 版本起已棄用。在 PHP >=5.5 上,請改用 ::class

定義於: yii\base\BaseObject::className()

傳回此類別的完整限定名稱。

public static string className ( )
return string

此類別的完整限定名稱。

                public static function className()
{
    return get_called_class();
}

            
clearAutoDetectedAttributeTypes() 公有靜態方法

清除自動偵測到的 $attributeTypes 值在所有受影響的所有者類別中的內部靜態快取。

public static void clearAutoDetectedAttributeTypes ( )

                public static function clearAutoDetectedAttributeTypes()
{
    self::$_autoDetectedAttributeTypes = [];
}

            
detach() 公有方法

定義於: yii\base\Behavior::detach()

從元件分離行為物件。

預設實作將取消設定 $owner 屬性,並分離 events() 中宣告的事件處理常式。如果您覆寫此方法,請確保呼叫父類別實作。

public void detach ( )

                public function detach()
{
    if ($this->owner) {
        foreach ($this->_attachedEvents as $event => $handler) {
            $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler);
        }
        $this->_attachedEvents = [];
        $this->owner = null;
    }
}

            
detectAttributeTypes() 保護方法

從所有者的驗證規則組成 $attributeTypes 的預設值。

protected array detectAttributeTypes ( )
return array

屬性類型映射。

                protected function detectAttributeTypes()
{
    $attributeTypes = [];
    foreach ($this->owner->getValidators() as $validator) {
        $type = null;
        if ($validator instanceof BooleanValidator) {
            $type = self::TYPE_BOOLEAN;
        } elseif ($validator instanceof NumberValidator) {
            $type = $validator->integerOnly ? self::TYPE_INTEGER : self::TYPE_FLOAT;
        } elseif ($validator instanceof StringValidator) {
            $type = self::TYPE_STRING;
        }
        if ($type !== null) {
            $attributeTypes += array_fill_keys($validator->getAttributeNames(), $type);
        }
    }
    return $attributeTypes;
}

            
events() 公有方法

宣告 $owner 的事件的事件處理常式。

子類別可以覆寫此方法,以宣告應附加到 $owner 元件事件的 PHP 回呼。

當行為附加到擁有者時,回呼將附加到 $owner 的事件;當行為從元件分離時,它們將從事件中分離。

回呼可以是以下任何一種:

  • 此行為中的方法:'handleClick',等效於 [$this, 'handleClick']
  • 物件方法:[$object, 'handleClick']
  • 靜態方法:['Page', 'handleClick']
  • 匿名函數:function ($event) { ... }

以下範例:

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events ( )
return array

事件(陣列鍵)和對應的事件處理常式方法(陣列值)。

                public function events()
{
    $events = [];
    if ($this->typecastAfterValidate) {
        $events[Model::EVENT_AFTER_VALIDATE] = 'afterValidate';
    }
    if ($this->typecastBeforeSave) {
        $events[BaseActiveRecord::EVENT_BEFORE_INSERT] = 'beforeSave';
        $events[BaseActiveRecord::EVENT_BEFORE_UPDATE] = 'beforeSave';
    }
    if ($this->typecastAfterSave) {
        $events[BaseActiveRecord::EVENT_AFTER_INSERT] = 'afterSave';
        $events[BaseActiveRecord::EVENT_AFTER_UPDATE] = 'afterSave';
    }
    if ($this->typecastAfterFind) {
        $events[BaseActiveRecord::EVENT_AFTER_FIND] = 'afterFind';
    }
    return $events;
}

            
hasMethod() 公有方法

定義於: yii\base\BaseObject::hasMethod()

傳回一個值,指示是否已定義方法。

預設實作是對 php 函數 method_exists() 的呼叫。當您實作 php 魔術方法 __call() 時,您可以覆寫此方法。

public boolean hasMethod ( $name )
$name string

方法名稱

return boolean

方法是否已定義

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() public method

定義於: yii\base\BaseObject::hasProperty()

傳回一個值,指示是否已定義屬性。

屬性被定義如果

  • 類別具有與指定名稱相關聯的 getter 或 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

參見

public boolean hasProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否被定義

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
init() public method

定義於: yii\base\BaseObject::init()

初始化物件。

在物件使用給定配置初始化之後,此方法會在建構函式的結尾被調用。

public void init ( )

                public function init()
{
}

            
resetOldAttributes() protected method

重置指定屬性的舊值。

protected void resetOldAttributes ( )

                protected function resetOldAttributes()
{
    if ($this->attributeTypes === null) {
        return;
    }
    $attributes = array_keys($this->attributeTypes);
    foreach ($attributes as $attribute) {
        if ($this->owner->canSetOldAttribute($attribute)) {
            $this->owner->setOldAttribute($attribute, $this->owner->{$attribute});
        }
    }
}

            
typecastAttributes() public method

根據 $attributeTypes 轉換所有者屬性的類型。

public void typecastAttributes ( $attributeNames null )
$attributeNames array|null

應進行類型轉換的屬性名稱列表。如果此參數為空,則表示 $attributeTypes 中列出的任何屬性都應進行類型轉換。

                public function typecastAttributes($attributeNames = null)
{
    $attributeTypes = [];
    if ($attributeNames === null) {
        $attributeTypes = $this->attributeTypes;
    } else {
        foreach ($attributeNames as $attribute) {
            if (!isset($this->attributeTypes[$attribute])) {
                throw new InvalidArgumentException("There is no type mapping for '{$attribute}'.");
            }
            $attributeTypes[$attribute] = $this->attributeTypes[$attribute];
        }
    }
    foreach ($attributeTypes as $attribute => $type) {
        $value = $this->owner->{$attribute};
        if ($this->skipOnNull && $value === null) {
            continue;
        }
        $this->owner->{$attribute} = $this->typecastValue($value, $type);
    }
}

            
typecastValue() protected method

將給定值轉換為指定的類型。

protected mixed typecastValue ( $value, $type )
$value mixed

要進行類型轉換的值。

$type string|callable

類型名稱或類型轉換 callable。

return mixed

類型轉換結果。

                protected function typecastValue($value, $type)
{
    if (is_scalar($type)) {
        if (is_object($value) && method_exists($value, '__toString')) {
            $value = $value->__toString();
        }
        switch ($type) {
            case self::TYPE_INTEGER:
                return (int) $value;
            case self::TYPE_FLOAT:
                return (float) $value;
            case self::TYPE_BOOLEAN:
                return (bool) $value;
            case self::TYPE_STRING:
                if (is_float($value)) {
                    return StringHelper::floatToString($value);
                }
                return (string) $value;
            default:
                throw new InvalidArgumentException("Unsupported type '{$type}'");
        }
    }
    return call_user_func($type, $value);
}