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 属性类型转换映射,格式为:属性名 => 类型。 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 公共属性

属性类型转换映射,格式为:属性名 => 类型。类型可以通过 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 公共属性

是否在从数据库中检索拥有者模型数据后(查找或刷新后)执行类型转换。可以禁用此选项以提高性能。例如,在 yii\db\ActiveRecord 使用的情况下,查找后进行类型转换在大多数情况下都不会带来好处,因此可以禁用。请注意,在此行为附加到模型后,更改此选项值将无效。

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

是否在保存拥有者模型(插入或更新)后执行类型转换。可以禁用此选项以提高性能。例如,在 yii\db\ActiveRecord 使用的情况下,保存后进行类型转换不会带来任何好处,因此可以禁用。请注意,在此行为附加到模型后,更改此选项值将无效。

public boolean $typecastAfterSave false
$typecastAfterValidate 公共属性

是否在拥有者模型验证后执行类型转换。请注意,只有在验证成功的情况下才会执行类型转换,例如拥有者模型没有错误。请注意,在此行为附加到模型后,更改此选项值将无效。

$typecastBeforeSave 公共属性

是否在保存拥有者模型(插入或更新)之前执行类型转换。可以禁用此选项以提高性能。例如,在 yii\db\ActiveRecord 使用的情况下,保存前进行类型转换不会带来任何好处,因此可以禁用。请注意,在此行为附加到模型后,更改此选项值将无效。

方法详情

隐藏继承的方法

__call() 公共方法

定义于: yii\base\BaseObject::__call()

调用不是类方法的命名方法。

不要直接调用此方法,因为它是一个 PHP 魔术方法,当调用未知方法时会隐式调用。

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

方法名称

$params array

方法参数

返回值 mixed

方法返回值

抛出 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

属性名称

返回值 mixed

属性值

抛出 yii\base\UnknownPropertyException

如果未定义属性

抛出 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.ac.cn/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

属性名称或事件名称

返回值 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

属性值

抛出 yii\base\UnknownPropertyException

如果未定义属性

抛出 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.ac.cn/manual/en/function.unset.php

public void __unset ( $name )
$name string

属性名称

抛出 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

是否将成员变量视为属性

返回值 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

是否将成员变量视为属性

返回值 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 ( )
返回值 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 ( )
返回值 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 事件的事件处理程序。

子类可以覆盖此方法来声明应将哪些 PHP 回调附加到 $owner 组件的事件。

当行为附加到所有者时,回调将附加到 $owner 的事件;当行为从组件分离时,它们将从事件分离。

回调可以是以下任何一种

  • 此行为中的方法:'handleClick',等效于 [$this, 'handleClick']
  • 对象方法:[$object, 'handleClick']
  • 静态方法:['Page', 'handleClick']
  • 匿名函数:function ($event) { ... }

以下是一个示例

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public 数组 events ( )
返回值 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 布尔值 hasMethod ( $name )
$name string

方法名称

返回值 boolean

方法是否已定义

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

            
hasProperty() 公共方法

定义于: yii\base\BaseObject::hasProperty()

返回一个值,指示属性是否已定义。

如果满足以下条件,则属性被定义为

  • 类具有与指定名称关联的 getter 或 setter 方法(在这种情况下,属性名称不区分大小写);
  • 类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另请参阅

public 布尔值 hasProperty ( $name, $checkVars true )
$name string

属性名称

$checkVars boolean

是否将成员变量视为属性

返回值 boolean

属性是否已定义

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

            
init() 公共方法

定义于: yii\base\BaseObject::init()

初始化对象。

此方法在构造函数结束时调用,在对象使用给定配置初始化后调用。

public void init ( )

                public function init()
{
}

            
resetOldAttributes() 受保护方法

重置命名属性的旧值。

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() 公共方法

根据 $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 混合 typecastValue ( $value, $type )
$value mixed

要进行类型转换的值。

$type 字符串|可调用

类型名称或类型转换可调用。

返回值 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);
}