mohamedhabibwork / laravel-model-transformers
复杂模型属性的简单转换层。
Requires
- php: >=5.3.0
- illuminate/support: ~5|~6|~7|~8|~9|~10
Requires (Dev)
- orchestra/testbench: >=3
- phpunit/phpunit: >=4
This package is auto-updated.
Last update: 2024-09-09 17:18:55 UTC
README
此包帮助API开发者轻松将Eloquent模型转换为可转换为JSON的数组。
以下是如何使用它的示例,假设你有一个包含以下数据的模型
{ "name": "iPhone", "type": 1 }
在这里,你使用一个数值来表示不同类型,你还在模型中有一个将数值映射到字符串的修改器。
在控制器内部,我们可以将模型转换为更友好的API结构。
<?php class SomeController{ function getIndex(){ $product = Product::find(1); return response([ "product" => ProductTransformer::transform($product) ]); } }
上面的代码将生成一个可能看起来像这样的JSON字符串
{ "product": { "name": "iPhone", "type": { "key": 1, "name": "Mobile Phone" } } }
安装
首先通过Composer安装包。在你的终端中运行以下命令
composer require themsaid/laravel-model-transformers
Composer完成后,将包服务提供者在config/app.php
中的提供者数组中添加
Themsaid\Transformers\TransformersServiceProvider::class
最后发布配置文件
php artisan vendor:publish --provider="Themsaid\Transformers\TransformersServiceProvider"
这就完成了。
使用方法
通过扩展AbstractTransformer类创建一个模型转换器类
<?php class CategoryTransformer extends Themsaid\Transformers\AbstractTransformer { public function transformModel(Model $item) { $output = [ 'name' => $item->name, 'type' => [ 'key' => $item->type, 'name' => $item->typeName ], ]; return $output; } }
现在你可以在任何控制器中调用转换器
<?php return response( CategoryTransformer::transform( Category::find(1) ) );
你还可以传递一个集合,结果将是一个转换后的模型数组
<?php return response( CategoryTransformer::transform( Category::all() ) );
处理关系
此包包含两个处理关系的有用方法,第一个方法可以帮助你知道特定的关系是否是懒加载的
isRelationshipLoaded()
<?php class ProductTransformer extends AbstractTransformer { public function transformModel(Model $item) { $output = array_only($item->toArray(), ['name', 'id']); if ($this->isRelationshipLoaded($item, 'tags')) { $output['tags'] = TagTransformer::transform($item->tags); } return $output; } }
现在只有当标签是懒加载的时候,它们才会出现在$output数组中,这有助于在查询具有关系的模型时记住要懒加载。
isLoadedFromPivotTable()
此方法可以帮助你知道模型是否是从多对多关系加载的,当表中存在枢纽数据并且你想展示它们时,这非常有用。
<?php class TagTransformer extends AbstractTransformer { public function transformModel(Model $item) { $output = array_only($item->toArray(), ['name', 'id']); if ($this->isLoadedFromPivotTable($item, 'products_tags')) { $output['relationship_data'] = [ 'is_active' => $item->pivot->is_active, ]; } return $output; } }
传递选项到转换器
你可能需要从控制器向转换器传递一些选项,你可以通过向transform()
方法提供选项数组作为第二个参数来实现这一点
<?php CategoryTransformer::transform($category, ['hide_admin_id' => true])
现在从CategoryTransformer内部,你可以检查选项参数
<?php class CategoryTransformer extends AbstractTransformer { public function transformModel(Model $item) { $output = []; if (@$this->options['hide_admin_id']) { unset($output['admin_id']); } return $output; } }
使用简写方法
此包附带了一个简写方法,用于应用模型或集合的转换
<?php class SomeController{ function getIndex(){ $product = Product::find(1); return response([ "product" => transform($product) ]); } }
使用transform()
方法,该包根据作为第一个参数传递的模型或集合查找合适的转换器。
默认情况下,它假设所有转换器都位于App\Transformers
命名空间下,你可以在配置文件中更改此行为。
你还可以将选项作为第二个参数传递到转换器中
<?php transform(Model::find(1), ['use_nl2br' => true])