eherrera / eloquent-custom-attributes
Laravel的Eloquent ORM的属性处理
dev-master
2018-12-09 21:44 UTC
Requires
- php: >=5.4.0
Requires (Dev)
- laravel/framework: >=4.0
- phpunit/phpunit: ~4.3
- squizlabs/php_codesniffer: ~1.0
This package is not auto-updated.
Last update: 2024-09-24 22:05:35 UTC
README
这个小型库允许你为Eloquent模型定义自定义(虚拟)属性,并使用它们与真实属性交互(或选择不交互)。
安装
- 简单的Composer安装即可:
composer require eherrera/eloquent-custom-attributes:dev-master
(设置你喜欢的版本要求)
使用
- 将
CustomAttributeHelperTrait
添加到你的模型中,并将任意数量的各种属性处理特性添加到你的模型中 - 定义
$customAttributes
属性,并列出属性名及其处理类 - 重写Eloquent的
getAttribute
和setAttribute
方法,以便它们与自定义属性一起工作 - 之后,你可以像平时一样使用属性。请参阅下面的示例
/** * @property array $json_meta_data This attribute is actually of 'string' * type in database and in model. * But we can work with it just like * it is array delegating all underlying * operations to JsonAttrHandlerTrait */ class Invoice extends Eloquent { use CustomAttributeHelperTrait; use JsonAttrHandlerTrait; protected $customAttributes = [ 'json_meta_data' => JsonAttrHandlerTrait::class, ]; /** * We have to override Eloquent's getAttribute() / * setAttribute() on the model directly (not in CustomAttributeHelperTrait) * because you might wish to do something in those methods yourself */ public function getAttribute($key) { if ($this->isCustomAttribute($key)) { return $this->getCustomAttribute($key); } return parent::getAttribute($key); } public function setAttribute($key, $value) { if ($this->isCustomAttribute($key)) { $this->setCustomAttribute($key, $value); return; } parent::setAttribute($key, $value); } /** * Just some simple class to show actual work with model ;) */ class Main { public function main() { $invoice = Invoice::findOrFail(1); $invoice->json_meta_data = ['key' => 'value']; $invoice->json_meta_data['key_next'] = 'value_next'; $invoice->save(); } }
有趣
- 自定义属性名可以与Laravel模型的真实属性名相同。在这种情况下,自定义属性将隐藏真实属性,并且与之的交互将通过相应的特性进行(当然,你仍然可以通过
$model->attributes[]
访问原始属性值)。但当然,如果你需要两者都可见,你可以为自定义属性使用另一个名称来与真实属性交互 - 你可以有一个自定义属性(例如
date
属性)与模型的好几个真实属性交互(例如day
、month
和year
,如果需要的话,可以分别交互)
扩展
如果你想实现自己的自定义属性处理器,你只需实现负责值转换的特性即可
- 此类特性的命名约定为
<typeName>AttrHandlerTrait
- 属性处理特性必须实现两个方法:
handleGetAttribute<typeName>
和handleSetAttribute<typeName>
。例如,检查Json\JsonAttrHandlerTrait
- 在特性中注意方法命名。不要使它们太常见,因为它们必须与Eloquent模型可能使用的其他特性的方法良好共存
- 如果你的自定义属性表示复杂类型(不仅仅是字符串或数字),请考虑为其创建包装器。此类包装器的示例可以是
ArrayAttributeWrapper
。它封装一个数组值,提供对它的访问,并在属性更改时更新相应的模型。包装器被缓存,因此可以从脚本中的任何部分多次访问属性