dfware / ar-dynattribute
提供动态ActiveRecord属性,以序列化状态存储在单个字段中
Requires
- yiisoft/yii2: ~2.0.14
This package is auto-updated.
Last update: 2024-09-27 19:57:36 UTC
README
安装此扩展的首选方式是通过 composer.
运行以下命令之一:
composer require dfware/ar-dynattribute
或添加
"dfware/ar-dynattribute": "*"
到您的composer.json文件的require部分。
用法
此扩展提供动态ActiveRecord属性,存储在单个字段中以序列化状态。例如:假设我们创建了一个网站,登录用户可以自定义其外观,如更改颜色方案或启用/禁用侧边栏等。为了使这种定制持久化,所有用户的选择都应该存储在数据库中。通常,每个视图设置都应该在'user'表中有一个自己的列。然而,在您的应用程序正在开发中且新设置快速出现的情况下,这不是很实际。因此,使用单个文本字段是有意义的,该字段将存储所有选择的视图参数的序列化字符串。如果引入了新选项,则无需更改'user'表的架构。创建'user'表的迁移可能看起来如下:
class m??????_??????_create_user extends \yii\db\Migration { public function up() { $this->createTable('User', [ 'id' => $this->primaryKey(), 'username' => $this->string()->notNull(), 'email' => $this->string()->notNull(), 'passwordHash' => $this->string()->notNull(), // ... 'viewParams' => $this->text(), // field, which stores view parameters in serialized state ]); } public function down() { $this->dropTable('User'); } }
注意!总的来说,这种数据存储方法是一种 不良 实践,不建议使用。其主要缺点是在搜索查询中无法使用动态属性。它仅适用于直接设置和读取单个记录的属性,并且永远不会用于筛选查询。
提示:如果您正在使用具有内置JSON支持的现代数据库管理系统(例如MySQL >= 5.5或PostgreSQL),则可以将动态属性存储在'JSON'类型列中而不是纯文本,但是您必须自己处理可能出现的搜索条件组合 - 此扩展不提供对此的明确支持。
此扩展提供了支持动态属性的ActiveRecord行为 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior]]。例如
use yii\db\ActiveRecord; use yii2tech\ar\dynattribute\DynamicAttributeBehavior; class User extends ActiveRecord { public function behaviors() { return [ 'dynamicAttribute' => [ 'class' => DynamicAttributeBehavior::className(), 'storageAttribute' => 'viewParams', // field to store serialized attributes 'dynamicAttributeDefaults' => [ // default values for the dynamic attributes 'bgColor' => 'green', 'showSidebar' => true, ], ], ]; } public static function tableName() { return 'User'; } // ... }
一旦附加 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior]],它允许其所有者像常规属性一样操作动态属性。在模型保存时,它们将被序列化并存储在持有字段中。在从数据库中检索记录后,第一次尝试读取动态属性将反序列化它们并准备使用。例如
$model = new User(); // ... $model->bgColor = 'red'; $model->showSidebar = false; $model->save(); // 'bgColor' and 'showSidebar' are serialized and stored at 'viewParams' echo $model->viewParams; // outputs: '{"bgColor": "red", "showSidebar": false}' $refreshedModel = User::findOne($model->getPrimaryKey()); echo $refreshedModel->bgColor; // outputs 'red' echo $refreshedModel->showSidebar; // outputs 'false'
您可以使用动态属性作为常规ActiveRecord属性。例如:您可以指定它们的验证规则,并通过网页表单获取它们的值。
注意:请记住,动态属性与ActiveRecord实体字段不对应,因此某些特定的ActiveRecord方法(如
updateAttributes()
)对它们不起作用。
默认值设置
如您从上述示例中注意到的,您可以通过 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$dynamicAttributeDefaults]] 提供动态属性的默认值。因此,一旦您需要为模型添加额外的动态属性,您只需更新相应的值,而无需对数据库执行任何更新。
class User extends ActiveRecord { public function behaviors() { return [ 'dynamicAttribute' => [ 'class' => DynamicAttributeBehavior::className(), 'storageAttribute' => 'viewParams', 'dynamicAttributeDefaults' => [ 'bgColor' => 'green', 'showSidebar' => true, 'fontColor' => 'black', // newly added attribute ], ], ]; } // ... } $newModel = new User(); echo $newModel->bgColor; // outputs 'green' echo $newModel->showSidebar; // outputs 'true' $oldModel = User::find()->orderBy(['id' => SORT_ASC])->limit(1)->one(); echo $oldModel->viewParams; // outputs: '{"bgColor": "red", "showSidebar": false}' echo $oldModel->fontColor; // outputs: 'black'
注意:您可以通过禁用 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$saveDynamicAttributeDefaults]] 选项来排除具有默认值的动态属性,从而禁用其保存。
限制动态属性列表
动态属性默认值设置不仅有用,而且在一般情况下是必要的。此列表对可能的动态属性名称施加了限制。只有指定了默认值的属性才能从模型中设置或读取。这可以防止由代码中的拼写错误引起的可能错误。例如
$newModel = new User(); $newModel->bgColor = 'blue'; // works fine $newModel->unExistingAttribute = 10; // throws an exception!
然而,有时有必要存储无法预测的属性列表。例如,保存来自某些外部服务的响应字段。在这种情况下,您可以使用 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$allowRandomDynamicAttribute]] 禁用对属性设置器进行的检查。如果将其设置为 true
,您将能够在 dynamicAttributeDefaults
中设置任何动态属性,无论它们是否已声明。
注意:您还可以使用 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::setDynamicAttributes()]] 方法绕过命名限制。此方法将设置提供的所有属性而无需任何检查。
您还可以使用 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$dynamicAttributeSaveFilter]] 控制要实际保存的动态属性列表。如果设置为 true
,它将排除任何不在 dynamicAttributeDefaults
选项中列出的属性。您还可以将其指定为 PHP 回调,该回调将执行一些自定义过滤。此选项允许您删除过去存在的但不再有效的旧动态属性。
序列化设置
默认情况下,[[\yii2tech\ar\dynattribute\DynamicAttributeBehavior]] 以 JSON 格式保存动态属性。但是,您可以通过 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$serializer]] 设置为它们设置另一个序列化程序。此扩展中可用以下序列化程序
- [[\yii2tech\ar\dynattribute\JsonSerializer]] - 以 JSON 格式存储数据
- [[\yii2tech\ar\dynattribute\PhpSerializer]] - 使用 PHP 的
serialize()
/unserialize()
函数存储数据 - [[\yii2tech\ar\dynattribute\CallbackSerializer]] - 通过自定义序列化 PHP 回调存储数据
- [[\yii2tech\ar\dynattribute\JsonExpressionSerializer]] - 处理 [[yii\db\JsonExpression]] 实例,支持使用 'JSON' 数据库列类型。
请参阅特定序列化程序类以获取更多详细信息。