yii1tech / model-typecast
允许在Yii1中对模型和ActiveRecord属性进行类型转换
Requires
- php: >=7.1
- yiisoft/yii: ~1.1.0
Requires (Dev)
- nesbot/carbon: ^2.67
- phpunit/phpunit: ^6.0 || ^7.0 || ^8.0 || ^9.3 || ^10.0.7
This package is auto-updated.
Last update: 2024-09-22 17:34:24 UTC
README
为Yii 1的模型属性类型转换扩展
本扩展为Yii1模型和ActiveRecord属性类型转换提供支持。
有关许可信息,请参阅LICENSE文件。
安装
安装此扩展的最佳方式是通过composer。
运行以下命令之一:
php composer.phar require --prefer-dist yii1tech/model-typecast
或者
"yii1tech/model-typecast": "*"
将其添加到您的composer.json文件中的"require"部分。
用法
此扩展为Yii1模型和ActiveRecord自动属性类型转换提供支持。它通过使用\yii1tech\model\typecast\TypecastBehavior
行为来实现。它应该附加到\CModel
或\CActiveRecord
派生类。例如
<?php use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'id' => TypecastBehavior::TYPE_INTEGER, 'amount' => TypecastBehavior::TYPE_INTEGER, 'price' => TypecastBehavior::TYPE_FLOAT, 'is_active' => TypecastBehavior::TYPE_BOOLEAN, 'created_at' => TypecastBehavior::TYPE_DATETIME, 'json_data' => TypecastBehavior::TYPE_ARRAY_OBJECT, ], 'typecastAfterValidate' => true, 'typecastBeforeSave' => false, 'typecastAfterSave' => true, 'typecastAfterFind' => true, ], ]; } // ... }
提示:您可以将
\yii1tech\model\typecast\TypecastBehavior::$attributeTypes
留空 - 在这种情况下,其值将自动检测:对于ActiveRecord,基于所有者数据库表模式,对于常规模型,基于验证规则。
在上面的示例中,以下情况下将自动执行属性类型转换
- 模型成功验证后
- 模型成功保存后
- 模型从数据库检索后
例如
<?php $model = new Item(); $model->setAttributes([ 'name' => 'item name', 'price' => '10.50', 'amount' => '14', 'is_active' => '1', ]); if ($model->validate()) { var_dump($model->id); // outputs: int(123456) var_dump($model->price); // outputs: float(10.5) var_dump($model->amount); // outputs: int(14) var_dump($model->is_active); // outputs: bool(true) } $model = Item::model()->findByPk($id); var_dump($model->id); // outputs: int(12345) var_dump($model->amount); // outputs: int(18) var_dump($model->is_active); // outputs: bool(true)
您可以通过调用\yii1tech\model\typecast\TypecastBehavior::typecastAttributes()
方法在任何时间手动触发属性类型转换
<?php $model = new Item(); $model->price = '38.5'; $model->is_active = 1; $model->typecastAttributes(); var_dump($model->price); // outputs: float(38.5) var_dump($model->is_active); // outputs: bool(true)
JSON类型转换
此行为允许在模型保存时自动将数组或可遍历对象转换为JSON字符串。例如
<?php $model = new Item(); $model->json_data = [ // will be saved in DB as '{foo: "bar"}' 'foo' => 'bar', ]; $model->save();
注意:即使没有直接属性类型指定,也会发生此类转换。
您可以将JSON列值类型转换为纯array
或\ArrayObject
实例。纯数组消耗较少的内存,但无法写入其特定的内部键。\ArrayObject
允许自由操作内部键,但请注意,其值总是通过引用传递。
<?php // in case mapping in `attributeTypes` is set to `TypecastBehavior::TYPE_ARRAY` use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'json_data' => TypecastBehavior::TYPE_ARRAY, ], ], ]; } // ... } $model = Item::model()->findByPk($id); var_dump($model->json_data); // outputs: array(1) {...} var_dump($model->json_data['foo']); // outputs: string(bar) $model->json_data['foo'] = 'new value'; // PHP E_NOTICE: Indirect modification of overloaded property Item::$json_data has no effect! $model->json_data = [ // no problem 'foo' => 'new value', ]; $model->save(); // in case mapping in `attributeTypes` is set to `TypecastBehavior::TYPE_ARRAY_OBJECT` use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'json_data' => TypecastBehavior::TYPE_ARRAY_OBJECT, ], ], ]; } // ... } $model = Item::model()->findByPk($id); var_dump($model->json_data); // outputs: object(ArrayObject) {...} var_dump($model->json_data['foo']); // outputs: string(bar) $model->json_data['foo'] = 'new value'; // no problem $jsonDataCopy = $model->json_data; // new variable holds the reference to `\ArrayObject` instance! $jsonDataCopy['foo'] = 'value from copy'; // changes value of `$model->json_data`! var_dump($model->json_data['foo']); // outputs: string(value from copy) $model->save();
DateTime类型转换
此行为允许在模型保存时自动将\DateTime
实例转换为ISO日期时间字符串。例如
<?php use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'created_at' => TypecastBehavior::TYPE_DATETIME, ], ], ]; } // ... } $model = new Item(); $model->created_at = new DateTime('now'); // will be saved in DB as '2023-12-22 10:14:17' $model->save(); $model = Item::model()->findByPk($id); var_dump($model->created_at); // outputs: object(DateTime)
如果您使用整数Unix时间戳存储日期,则可以使用\yii1tech\model\typecast\TypecastBehavior::TYPE_TIMESTAMP
进行正确转换。例如
<?php use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'created_at' => TypecastBehavior::TYPE_TIMESTAMP, ], ], ]; } // ... } $model = new Item(); $model->created_at = new DateTime('now'); // will be saved in DB as '1703257478' $model->save(); $model = Item::model()->findByPk($id); var_dump($model->created_at); // outputs: object(DateTime)
此扩展还支持nesbot/carbon包。为了将日期转换为\Carbon\Carbon
,您应使用以下类型
\yii1tech\model\typecast\TypecastBehavior::TYPE_DATETIME_CARBON
\yii1tech\model\typecast\TypecastBehavior::TYPE_TIMESTAMP_CARBON
自定义类型转换
您可以使用在\yii1tech\model\typecast\TypecastBehavior::$attributeTypes
中用作类型指定的可调用来指定任何自定义属性类型转换。例如
<?php use yii1tech\model\typecast\TypecastBehavior; class Item extends CActiveRecord { public function behaviors() { return [ 'typecastBehavior' => [ 'class' => TypecastBehavior::class, 'attributeTypes' => [ 'heap_data' => function ($value) { if (is_object($value)) { return $value; } $heap = new \SplMaxHeap(); foreach (json_decode($value) as $element) { $heap->insert($element); } return $heap; }, ], ], ]; } // ... } $model = Item::model()->findByPk($id); var_dump($model->heap_data); // outputs: object(SplMaxHeap)