pozitronik / yii2-dynamic-attributes
yii2模型的动态属性
Requires
- php: >=8.0
- cusodede/yii2-default-controller: ^1.0.0
- kartik-v/yii2-widget-select2: ^2.2.3
- pozitronik/yii2-badgewidget: ^2.0.0
- pozitronik/yii2-traits: ^1.0.0
Requires (Dev)
- codeception/codeception: ^4.1
- codeception/module-asserts: ^1.3
- codeception/module-cli: dev-master
- codeception/module-db: ^1.1
- codeception/module-filesystem: ^1.0
- codeception/module-phpbrowser: ^1.0.0
- codeception/module-rest: ^1.3.1
- codeception/module-yii2: ^1.1
- phpunit/phpunit: ^9.5
- vlucas/phpdotenv: ^5.4.1
- yiisoft/yii2: dev-master
- yiisoft/yii2-bootstrap4: ~2.0.10
README
ActiveRecord模型的动态属性。
安装
推荐通过composer安装扩展。
执行
php composer.phar require pozitronik/yii2-dynamic-attributes "^1.0.0"
或添加
"pozitronik/yii2-dynamic-attributes": "^1.0.0"
到项目中的composer.json
文件的require部分。
迁移
模块将数据存储在由以下命令创建的表中:
php yii migrate/up --migrationPath=@vendor/pozitronik/yii2-dynamic-attributes/migrations
迁移将创建的表名列表可以在文件migrations/m000000_000000_create_dynamic_attributes_tables.php
中查看。
概念和示例
通常在设计应用程序时,我们提前知道我们将与哪些数据集一起工作,并据此模拟类,例如,创建适合这些数据的数据库结构。但有时需要允许用户在运行时自行定义数据集。
- 就像Excel一样! - 就像Excel一样!
此组件通过两个步骤将动态属性的支持添加到ActiveRecord模型中。
- 将类别名写入模型的配置,或者动态添加
DynamicAttributes::setClassAlias(MyTableModel::class, 'myTableModel');
- 将
DynamicAttributesTrait
特质添加到您的模型中
<?php declare(strict_types = 1); namespace app\models; use pozitronik\dynamic_attributes\traits\DynamicAttributesTrait; use yii\db\ActiveRecord; class MyTableModel extends ActiveRecord { use DynamicAttributesTrait; /*Прочий обычный код*/ }
现在可以在该模型的实例中无限制地创建任何属性
$tableModel = new MyTableModel(); $tableModel->my_cool_attribute = 'произвольный атрибут' /*или даже*/ $tableModel->{'числовой атрибут'} = 100500; /*или даже так*/ $tableModel->{'❤️Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮❤️'} = 'yes'; $tableModel->save(); /*значения динамических атрибутов сохраняются вместе с моделью, и будут доступны и далее*/ $otherTableModel = MyTableModel::find()->where(['id' => $tableModel->id])->one(); $otherTableModel->{'❤️Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮❤️'} === 'yes';// => true
可以在测试tests/unit/DynamicAttributesTest.php中查看动态属性的示例操作。
在search模型中使用
要在search模型中使用动态属性,需要执行以下步骤
- 在search模型中添加特质
DynamicAttributesSearchTrait
- 如果需要排序支持,将其添加到排序设置中
- 在search请求中添加过滤支持
对于第2-4点,已编写适配器以简化操作。
<?php declare(strict_types = 1); namespace app\models; use pozitronik\dynamic_attributes\traits\DynamicAttributesSearchTrait; use yii\data\ActiveDataProvider; /** * Class UsersSearch */ class MyTableModelSearch extends MyTableModel { /*Добавляем трейт*/ use DynamicAttributesSearchTrait; /** * @inheritdoc */ public function rules():array { /*Отдельно описывать правила для динамических атрибутов не нужно, они сгенерируются автоматически*/ return [ [['id'], 'integer'] ]; } /** * @param array $params * @return ActiveDataProvider */ public function search(array $params):ActiveDataProvider { $query = MyTableModel::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query ]); /*Добавляем сортировку*/ $dataProvider->setSort($this->adaptSort([ 'defaultOrder' => ['id' => SORT_ASC], 'attributes' => [ 'id' => [ 'asc' => ['id' => SORT_ASC], 'desc' => ['id' => SORT_DESC] ], ] ])); $this->load($params); $query->andFilterWhere(['id' => $this->id]); /*Добавляем поддержку фильтров*/ $this->adaptQuery($query); return $dataProvider; } }
现在可以像使用常规属性一样使用动态属性在GridView中(尽管您可能需要动态地将它们添加到网格中,但这并不困难)。
几乎...
一个小限制:在为模型属性生成HTML字段时(例如,在网格的过滤器中),使用了这些属性的名称。如上所示,动态属性可能被命名为无法从中生成任何好东西的名称。
为了解决这个问题,在执行期间为每个动态属性分配了一个别名,该别名用于在search模型(以及相应地,在HTML生成器)中代替直接属性名称。这样做是为了最大限度地减少开发人员的压力,但在必要时可以在测试tests/unit/DynamicAttributesSearchTest.php和代码中查看替换逻辑。
限制
- 当前版本仅针对PostgreSQL进行创建和测试。
- 目前不完全支持结构化数据类型(数组和对象)。允许创建和使用带有这些值的动态属性,但对其搜索和排序尚未实现。
配置
return [ // ... 'modules' => [ 'dynamic_attributes' => [ 'class' => DynamicAttributesModule::class, 'params' => [ 'models' => [/* Список алиасов классов в формате "Имя класса" => "алиас класса" */ MyTableModel:class => 'myTableModel' ], 'limitFloatPrecision' => true, /* Включает ограничение размера сохраняемых значений с плавающей точкой до 14 десятичных знаков, см. DynamicAttributesValues::$limitFloatPrecision */ 'cacheEnabled' => true, /* Включает кеширование всех данных модуля, если настроено глобально. Рекомендуется оставить включённым во избежание проблем производительности. */ ] ] ] //... ];
运行本地测试
将tests/.env.example
复制到tests/.env
,并根据您的本地环境修改配置。然后执行命令php vendor/bin/codecept run
。
性能测试
在配置文件 codeception.yml
中,将 modules: Yii2: transaction:
的值设置为 false
。在文件 tests/unit/IndexGeneratorTest.php
中,删除需要运行的测试的 @skip
指令。可选地,修改常量 TESTING_RECORDS_CNT
和 TESTING_SEARCH_REPEATS
的值。它们的值越大,用于计算最终结果的样本量就越大。要运行测试,请执行命令 php vendor/bin/codecept run tests/unit/IndexGeneratorTest.php
。
许可证
GNU GPL v3.0