yii2tech / ar-dynattribute
提供将动态ActiveRecord属性存储到单个字段中的序列化状态
Requires
- yiisoft/yii2: ~2.0.14
This package is auto-updated.
Last update: 2022-01-10 10:34:59 UTC
README
ActiveRecord 动态属性扩展 for Yii2
此扩展提供了将动态ActiveRecord属性存储到单个字段中的序列化状态。
有关许可证信息,请查看 LICENSE 文件。
安装
安装此扩展的首选方式是通过 composer。
运行以下命令之一:
php composer.phar require --prefer-dist yii2tech/ar-dynattribute
或
"yii2tech/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' 类型列中而不是纯文本,但您将不得不自行处理可能的搜索条件组合 - 此扩展不提供对此的明确支持。
此扩展提供了用于支持动态属性的 [[\yii2tech\ar\dynattribute\DynamicAttributeBehavior]] ActiveRecord 行为。例如
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属性。例如:您可以为它们指定验证规则,并通过Web表单获取它们的值。
注意:请注意,动态属性不对应于ActiveRecord实体字段,因此某些特定的ActiveRecord方法(如
updateAttributes()
)不适用于它们。
默认值设置
从上面的示例中您可能已经注意到,您可以通过[[\yii2tech\ar\dynattribute\DynamicAttributeBehavior::$dynamicAttributeDefaults]]为动态属性提供默认值。因此,一旦您需要为模型添加额外的动态属性,只需更新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'数据库列类型。
请参阅特定序列化器类以获取更多详细信息。