yii2tech/ar-dynattribute

此包已被废弃,不再维护。未建议替代包。

提供将动态ActiveRecord属性存储到单个字段中的序列化状态

资助包维护!
klimov-paul
Patreon

安装次数: 19,199

依赖项: 2

建议者: 0

安全: 0

星星: 43

关注者: 2

分支: 4

开放问题: 0

类型:yii2-extension

1.0.2 2018-09-19 11:51 UTC

This package is auto-updated.

Last update: 2022-01-10 10:34:59 UTC


README

12951949

ActiveRecord 动态属性扩展 for Yii2


此扩展提供了将动态ActiveRecord属性存储到单个字段中的序列化状态。

有关许可证信息,请查看 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方式是通过 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'数据库列类型。

请参阅特定序列化器类以获取更多详细信息。