クラス yii\behaviors\AttributeTypecastBehavior
AttributeTypecastBehavior は、モデル属性の自動型変換機能を提供します。
このビヘイビアは、MongoDBやRedisのようなスキーマレスデータベースでActiveRecordを使用する場合に非常に便利です。また、通常のyii\db\ActiveRecordや、yii\base\Modelに対しても、モデルのバリデーション後に厳密な属性型を維持するために役立ちます。
このビヘイビアは、yii\base\Modelまたはyii\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 |
公開メソッド
保護されたメソッド
メソッド | 説明 | 定義元 |
---|---|---|
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 |
プロパティの詳細
属性型キャストマップを、属性名 => 型 の形式で設定します。型は、生の値を引数として受け取り、型キャスト結果を返すPHPのcallableを使用して設定できます。例:
[
'amount' => 'integer',
'price' => 'float',
'is_active' => 'boolean',
'date' => function ($value) {
return ($value instanceof \DateTime) ? $value->getTimestamp(): (int) $value;
},
]
設定しない場合、属性型マップはオーナーのバリデーションルールから自動的に構成されます。
null
値の型キャストをスキップするかどうか。有効にした場合、null
と等しい属性値は型キャストされません(例:null
はnull
のまま)。そうでない場合は、$attributeTypesで設定された型に従って変換されます。
データベースからオーナーモデルのデータを取得した後に(findまたはrefreshの後)、型キャストを実行するかどうか。このオプションを無効にすると、パフォーマンスが向上する場合があります。たとえば、yii\db\ActiveRecordを使用する場合、find後の型キャストはほとんどの場合メリットがないため、無効にできます。このオプションの値を変更しても、このビヘイビアがモデルにアタッチされた後は効果がないことに注意してください。
オーナーモデルを保存(挿入または更新)した後に型キャストを実行するかどうか。このオプションを無効にすると、パフォーマンスが向上する場合があります。たとえば、yii\db\ActiveRecordを使用する場合、保存後の型キャストはほとんどの場合メリットがないため、無効にできます。このオプションの値を変更しても、このビヘイビアがモデルにアタッチされた後は効果がないことに注意してください。
オーナーモデルのバリデーション後に型キャストを実行するかどうか。型キャストは、バリデーションが成功した場合(例:オーナーモデルにエラーがない場合)にのみ実行されることに注意してください。このオプションの値を変更しても、このビヘイビアがモデルにアタッチされた後は効果がないことに注意してください。
オーナーモデルを保存(挿入または更新)する前に型キャストを実行するかどうか。このオプションを無効にすると、パフォーマンスが向上する場合があります。たとえば、yii\db\ActiveRecordを使用する場合、保存前の型キャストはほとんどの場合メリットがないため、無効にできます。このオプションの値を変更しても、このビヘイビアがモデルにアタッチされた後は効果がないことに注意してください。
メソッドの詳細
定義元: 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()");
}
定義元: yii\base\BaseObject::__construct()
コンストラクタ。
デフォルトの実装では次の2つのことを行います
- 指定された構成
$config
を使用してオブジェクトを初期化します。 - init()を呼び出します。
このメソッドが子クラスでオーバーライドされている場合は、次のことが推奨されます
- コンストラクタの最後のパラメータは、ここでの
$config
のような構成配列です。 - コンストラクタの最後に親の実装を呼び出します。
public void __construct ( $config = [] ) | ||
$config | array |
オブジェクトのプロパティを初期化するために使用される名前と値のペア |
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);
}
$this->init();
}
定義元: yii\base\BaseObject::__get()
オブジェクトプロパティの値を返します。
$value = $object->property;
を実行するときに暗黙的に呼び出されるPHPマジックメソッドであるため、このメソッドを直接呼び出さないでください。
また、__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);
}
定義元: yii\base\BaseObject::__isset()
プロパティが設定されているか、つまり定義されており、nullではないかを確認します。
isset($object->property)
を実行するときに暗黙的に呼び出されるPHPマジックメソッドであるため、このメソッドを直接呼び出さないでください。
プロパティが定義されていない場合は、falseが返されることに注意してください。
また、https://www.php.net/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;
}
定義元: yii\base\BaseObject::__set()
オブジェクトプロパティの値を設定します。
$object->property = $value;
を実行するときに暗黙的に呼び出されるPHPマジックメソッドであるため、このメソッドを直接呼び出さないでください。
また、__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);
}
}
定義元: yii\base\BaseObject::__unset()
オブジェクトプロパティを null に設定します。
unset($object->property)
を実行するときに暗黙的に呼び出されるPHPマジックメソッドであるため、このメソッドを直接呼び出さないでください。
プロパティが定義されていない場合、このメソッドは何もしないことに注意してください。プロパティが読み取り専用の場合は、例外がスローされます。
また、https://www.php.net/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」イベントを処理し、属性の型変換を確実にします。
public void afterFind ( $event ) | ||
$event | yii\base\Event |
イベントインスタンス。 |
public function afterFind($event)
{
$this->typecastAttributes();
$this->resetOldAttributes();
}
オーナーの「afterInsert」および「afterUpdate」イベントを処理し、属性の型変換を確実にします。
public void afterSave ( $event ) | ||
$event | yii\base\Event |
イベントインスタンス。 |
public function afterSave($event)
{
$this->typecastAttributes();
}
オーナーの「afterValidate」イベントを処理し、属性の型変換を確実にします。
public void afterValidate ( $event ) | ||
$event | yii\base\Event |
イベントインスタンス。 |
public function afterValidate($event)
{
if (!$this->owner->hasErrors()) {
$this->typecastAttributes();
}
}
ビヘイビアオブジェクトをコンポーネントにアタッチします。
デフォルトの実装では、$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];
}
}
オーナーの「beforeInsert」および「beforeUpdate」イベントを処理し、属性の型変換を確実にします。
public void beforeSave ( $event ) | ||
$event | yii\base\Event |
イベントインスタンス。 |
public function beforeSave($event)
{
$this->typecastAttributes();
}
定義元: 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);
}
定義元: 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);
}
::class
を使用してください。
定義元: yii\base\BaseObject::className()
このクラスの完全修飾名を返します。
public static string className ( ) | ||
return | string |
このクラスの完全修飾名。 |
---|
public static function className()
{
return get_called_class();
}
影響を受けるすべてのオーナー クラスにおける自動検出された $attributeTypes 値の内部静的キャッシュをクリアします。
public static void clearAutoDetectedAttributeTypes ( ) |
public static function clearAutoDetectedAttributeTypes()
{
self::$_autoDetectedAttributeTypes = [];
}
定義元: 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;
}
}
オーナーのバリデーションルールから $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;
}
$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;
}
定義元: 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);
}
定義元: yii\base\BaseObject::hasProperty()
プロパティが定義されているかどうかを示す値を返します。
プロパティが定義されるのは、
- クラスが、指定された名前に関連付けられたゲッターまたはセッターメソッドを持っている場合(この場合、プロパティ名は大小文字を区別しません)。
- クラスが、指定された名前のメンバ変数を持っている (
$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);
}
public void init ( ) |
public function init()
{
}
名前付き属性の古い値をリセットします。
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});
}
}
}
$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);
}
}
指定された型に値をキャストします。
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);
}
コメントするにはサインアップまたはログインしてください。