thinktomorrow / dynamic-attributes
轻松存储和检索优雅模型文档值
Requires
- php: ^8.1
- ext-json: *
- doctrine/dbal: ^3.1
- illuminate/database: ^8.12|^9.0|^10.0
Requires (Dev)
- orchestra/testbench: ^6.18|^7.5|^8.10
- phpunit/phpunit: ^9.5
- psalm/plugin-laravel: ^1.4|^2.0
- vimeo/psalm: ^4.8
README
此小包将类似NoSQL的存储行为添加到您的优雅模型中。它允许模型将json列值作为顶级属性进行交互。
安装
您可以通过Composer安装此包。
composer require thinktomorrow/dynamic-attributes
设置
以下是设置此包的快速方法。我们将假设您已经设置了一个优雅模型。
- 将json列添加到优雅模型的数据库方案中。默认情况下,它应该命名为
values
。 - 将
HasDynamicAttributes
特性添加到您的优雅模型中。 - 在模型中添加一个
dynamicKeys
属性,并用应存储和从json列检索的值键填充。
以下是一个示例设置
use Illuminate\Database\Eloquent\Model; use Thinktomorrow\DynamicAttributes\HasDynamicAttributes; class ExampleModel extends Model { + use HasDynamicAttributes; + protected $dynamicKeys = ['firstname', 'lastname']; // ... }
json列
在幕后,值会自动从json属性转换为JSON数组,反之亦然。在模型上,无需自定义优雅类型转换,因为特性本身将处理从存储值到存储值的转换。
动态属性最好存储为JSON数据库列,但字符串类型的列也应该没问题。JSON列将在需要查询数据库时使您的生活更加轻松。
默认情况下,数据库列名为 values
。您可以自由更改此名称。
用法
设置值:setDynamic(string $key, $value)
值可以像使用任何其他优雅属性一样设置。有一个 setDynamic($key, $value)
方法,允许您显式设置动态属性。
// Setting a dynamic attribute just like a regular attribute. $model = new ExampleModel(['firstname' => 'Ben']); // .. or by setting it after instantiation $model->firstname = 'Ben'; // Is the same as $model->setDynamic('firstname', 'Ben');
获取值:dynamic(string $key)
值可以像常规属性一样检索。您可以使用 dynamic($key)
方法来检索动态属性值。
// Retrieve a dynamic attribute just like a regular attribute $model = new ExampleModel(['firstname' => 'Ben']); $model->firstname; // Ben // Or via the 'dynamic' method $model->dynamic('firstname'); // Ben // In case that the value is an array, a second parameter is used to require a specific key of the array value. $model = new ExampleModel(['person' => ['name' => 'Ben', 'age' => 39]); $model->dynamic('person', 'name'); // Ben $model->dynamic('person', 'age'); // 39 // The 'dynamic' method allows for a default value in case the attribute isn't found $model->dynamic('xxx', null, 'default'); // default
检查值:isDynamic()
检查传递的键是否指的是动态属性键。
$model->isDynamic('firstname'); // true $model->isDynamic('xxx'); // false
原始值
您可以通过 rawDynamicValues
方法获取动态值的原始数组。
$model->rawDynamicValues() // outputs the entire array: ['firstname' => 'Ben']
本地化
动态属性是考虑到本地化构建的。
设置本地化值是通过传递区域设置作为嵌套键来完成的
// You can use dot syntax $model->setDynamic('title.en', 'My article title'); $model->setDynamic('title.nl', 'Mijn blogtitel'); // Optionally pass the locale as third argument $model->setDynamic('title', 'My article title', 'en');
检索本地化值
// When fetching the attribute without locale indication, // the current application locale will be used. $model->title; // My article title app()->setLocale('nl'); $model->title; // Mijn blogtitel // You can target a specific localized value with the dynamic() method $model->dynamic('title.en'); // My article title // If the localized value isn't found, null is returned $model->dynamic('title.fr'); // null
您还可以在模型上添加一个 dynamicLocales
属性。这是一个数组,应该包含模型的全部区域设置。这确保了当找不到本地化值时返回null值,而不是整个值数组。
use ...
class ExampleModel extends Model
{
use HasDynamicAttributes;
protected $dynamicKeys = ['title'];
+ protected $dynamicLocales = ['en', 'nl'];
}
更改数据库列名
默认列名设置为 values
。您可以通过在模型中覆盖 dynamicDocumentKey
来更改此名称,并返回您自定义的列/属性名称。
优雅方法继承
特性类覆盖了一些优雅方法。这些方法是: getAttribute
,setAttribute
,setRawAttributes
和 removeTableFromKey
。这是因为与优雅属性逻辑的内在联系以及优雅允许通过继承进行行为更改的方式。
如果您使用另一个也覆盖这些方法之一的特性,您将遇到方法冲突,并需要将特性方法别命名。
其他解决方案
还有一个提供类似功能的优秀包,那就是 spatie/laravel-schemaless-attributes。它也提供了类似NoSQL行为的JSON列,但采用了不同的方法。主要区别在于,我们的包允许处理顶级属性和本地化值,这是某些项目的需求。另一方面,使用Spatie的包,您可以添加多个'nosql'列,而我们的包目前无法实现这一点。
测试
composer test
安全
如果您发现任何与安全相关的问题,请通过电子邮件 dev@thinktomorrow.be 而不是使用问题跟踪器。
鸣谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅 许可证文件。