咨询/laravel-transformer

一种简单转换数据的方法,并提供了在Laravel应用程序中转换数据的一些辅助工具。

0.6.0 2022-10-18 13:08 UTC

README

Build Status Scrutinizer Code Quality

一种简单转换数据的方法,并提供了在Laravel应用程序中转换数据的一些辅助工具。

安装

  • 使用Composer安装Transformer: composer require konsulting/laravel-transformer

Laravel应用程序中的Transformer

  • Transformer使用了Illuminate\Support\CollectionIlluminate\Support\Arr,并需要这两个扩展。这些扩展可以在konsulting/laravel-extend-collections包中找到。
  • 您需要该包中的CollectionsServiceProvider以及您config/app.php中的TransformerServiceProvider

如果您正在使用Laravel 5.5,它们将自动注册。但是,如果您选择不自动注册,或者使用的是早期版本,请将以下内容添加到config/app.php

'providers' => [
    // Other service providers...

    Konsulting\Laravel\CollectionsServiceProvider::class,
    Konsulting\Laravel\Transformer\TransformerServiceProvider::class,
],
  • 可选地,将Transformer Facade添加到config/app.php
'aliases' => [
    // Other aliases...

    'Transformer' => Konsulting\Laravel\Transformer\TransformerFacade::class,
],
  • 可选地发布配置文件,并调整您想要使用的规则包。php artisan vendor:publish --provider=Konsulting\\Laravel\\Transformer\\TransformerServiceProvider --tag=config

Laravel应用程序之外的Transformer

  • Transformer使用了Illuminate\Support\CollectionIlluminate\Support\Arr。在Laravel应用程序之外,它将使用tighten/collect(从Laravel的Illuminate\Support中提取的Collection && Arr)来获取这些依赖项。
  • Transformer还需要对这些扩展进行一些扩展。这些扩展可以在konsulting/laravel-extend-collections包中找到。您需要手动注册这些扩展。
  • 您需要手动构建Transformer以在您的应用程序中使用。
    // Basic example

    use Konsulting\Laravel\Transformer\Transformer;
    use Konsulting\Laravel\Transformer\RulePacks\CoreRulePack;
    use Konsulting\Laravel\Transformer\RulePacks\CarbonRulePack;

    require __DIR__ . '/../vendor/autoload.php';

    // Extend Illuminate\Support\Arr and Illuminate\Support\Collection
    \Konsulting\Laravel\load_collection_extensions();

    // Build up Transformer
    $transformer = new Transformer([CoreRulePack::class, CarbonRulePack::class]);

    // Transformer now available to use, see Usage

用法

Transformer使用RulePacks来提供转换功能。RulePacks可以在构建Transformer时添加,或者在构建后使用addRulePackaddRulePacks方法添加。

一组规则可以在构建期间传递(当将相同的规则应用于不同的数据集时很有用),或者规则可以在执行转换时传递。

要转换数据,请使用transform方法。它接受要转换的数据的数组(或集合),以及可选的规则。

  • 规则以类似于Laravel Validator的方式呈现。它们提供了处理嵌套数据的功能,并遵循相同的字符串格式。
  • 规则数组按字段表达式索引,并提供了一个由|(管道)分隔的规则列表,用于应用这些规则。
  • 规则可以提供一个CSV格式的参数集。字段表达式可以使用*作为通配符来匹配该深度的元素,**作为特殊案例来匹配一切。
  • 规则序列将按提供的顺序构建。
    // using the $transformer built up earlier

    $rules = [
        '*' => 'drop_if_empty',
        'name' => 'trim',
        'contacts.*.name' => 'trim|uppercase'
    ];

    $data = [
        0 => '',
        'name' => '   Keoghan Litchfield   ',
        'contacts' => [
            ['name' => 'Robin'],
            ['name' => 'Roger'],
            ['name' => ''],
        ],
    ];

    $result = $transformer->transform($data, $rules);

    //    Outputs [
    //        'name' => 'Keoghan Litchfield',
    //        'contacts' => [
    //            ['name' => 'ROBIN'],
    //            ['name' => 'ROGER'],
    //        ],
    //    ];

转换助手

还有一个名为Transform的助手类,它可以方便地通过一个或多个规则转换单个值。Transform通过其构造函数接收一个Transformer实例,该实例提供转换逻辑并确定哪些规则可用。使用之前构建的Transformer实例

use Konsulting\Laravel\Transformer\Transform;

$transform = new Transform($transformer);

规则可以作为Transform对象的函数调用,要转换的值作为第一个参数传递,任何规则参数作为后续参数传递。

$transform->trim(' Some string to be trimmed   ');  // Outputs 'Some string to be trimmed'

$transform->regexReplace('testing', 'e', 'oa');     // Outputs 'toasting'

或者,可以通过 withRule()withRules() 方法(分别用于单个和多个规则)来传递规则。规则参数可以是单独的参数,也可以是一个数组。

// Single rule
$transform->withRule('  test  ', 'trim');                           // Outputs 'test'

// Single rule with parameters passed as separate arguments
$transform->withRule('test', 'regex_replace', 'e', 'oa');           // Outputs 'toast'

// Singe rule with parameters passed as an array
$transform->withRule('test', 'regex_replace', ['e', 'oa']);         // Outputs 'toast' as well

// Multiple rules passed as a sequential array
$transform->withRules('  test  ', ['trim', 'uppercase']);           // Outputs 'TEST'

// Multiple rules and parameters passed as an assocative array: [$rule => [$param1, $param2], $rule2 => []...]
$transform->withRules('--test--', [                                 // Outputs 'TOAST'
    'trim'          => ['-'],
    'regex_replace' => ['e', 'oa'],
    'uppercase'     => [],
]);

流畅式API

规则也可以流畅地调用:使用 input() 方法设置输入值,并使用 get() 获取结果。可以在这些方法之间链式调用任意数量的规则方法。

$transform->input(' hello ')
    ->trim()
    ->regexReplace('hello', 'world')
    ->uppercase()
    ->get();

// Outputs 'WORLD'

当使用流畅式API时,值不会作为参数传递给规则方法(因为它已经通过 input() 设置)。因此,传递给规则方法的任何参数都被视为规则参数。

withRule()withRules() 可以用来流畅地声明带有或不带有参数的规则

$transform->input($input)
    ->withRule('trim')
    ->uppercase()
    ->get();

$transform->input($input)
    ->lowercase()
    ->withRules(['trim', 'uppercase'])
    ->get();

可用的规则

我们提供了一些规则包以供使用,可以通过创建自己的规则包轻松扩展可用的规则。规则包按声明的顺序加载,较后加载的包中的方法会覆盖先加载的包。

参数名用 <param> 表示,可选参数用 [<param>] 表示。

核心规则包

清理
  • null_if_empty
  • null_if_empty_string
  • return_null_if_empty – 等同于 null_if_empty|bail_if_null
  • return_null_if_empty_string – 等同于 null_if_empty_string|bail_if_null
  • bail_if_null
  • drop_if_null
  • drop_if_empty
  • drop_if_empty_string
  • trim:[<character(s)_to_trim>] – 如果没有提供字符,则执行默认的PHP trim()。
类型转换
  • string - 转换为字符串,数组会转换为CSV,或对于无法表示为字符串的项目返回空字符串。
  • boolean
  • array
  • collection - 转换为 Illuminate\Support\Collection
  • json
  • float
  • integer
  • date_time:[timezone]
  • date_time_immutable:[timezone]
字符串操作
  • uppercase
  • lowercase
正则表达式和字符串替换
  • replace:<search_string>,<replace_string>
  • regex_replace:<search_regex>,<replace_string>
  • numeric
  • alpha
  • alpha_dash
  • alpha_num
  • alpha_num_dash

Carbon 规则包

  • carbon
  • date_format - 必需的格式参数。

相关字段规则包

  • null_with:<key>
  • drop_with:<key>
  • bail_with:<key>
  • null_without:<key>
  • drop without:<key>
  • bail_without:<key>

数字规则包

  • clamp:<min>,<max> - 限制一个数字在两个值之间

注意:键是数据集中另一个字段的点表示法键。

Laravel 辅助工具

我们经常使用 Laravel,因此在这里增加了一些额外的功能。

外观

使用外观可以在任何地方轻松访问 Transformer。

\Transformer::transform($data, $rules);

请求宏 transform

服务提供者将转换宏添加到 Illuminate\Http\Request 类。这使得在任何点上调用转换变得简单。该方法将请求对象传递回来以允许链式调用。

// Example Controller

namespace App\Http\Controllers;

use App\ContactRequest;
use Illuminate\Http\Request;

class ContactRequestsController
{
    // ...

    public function store(Request $request)
    {
        $request->transform([
            'name' => 'trim|uppercase',
            'message' => 'trim',
        ]);

        $this->validate($request, [
            'name' => 'required',
        ]);

        return ContactRequest::create(
            $request->only('name', 'message')
        );
    }
}

TransformingRequest 特性

此特性使表单请求在验证之前(即容器解析时)转换数据。

转换规则在 transformRules 方法中提供。

使用 TransformingRequest 特性

// Form Request

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Konsulting\Laravel\Transformer\TransformingRequest;

class ContactFormRequest extends FormRequest
{
    use TransformingRequest;

	  // ... other methods including rules()

    public function transformRules()
    {
        return [
            'name' => 'trim|uppercase',
            'message' => 'trim',
        ];
    }
// Controller

namespace App\Http\Controllers;

use App\ContactRequest;
use App\Http\Requests\ContactFormRequests;

class ContactRequestsController
{
    // ...

    public function store(ContactFormRequest $request)
    {
        return ContactRequest::create(
            $request->only('name', 'message')
        );
    }
}

中间件

TransformRequest 中间件根据配置的规则对请求进行转换。这些规则在配置文件的 middleware_rules 键中指定,如 用法 中所述。

要将中间件注册到项目中使用,请将以下行添加到项目的 App/Http/Kernel.php 文件中

'transform_data' => \Konsulting\Laravel\Transformer\Middleware\TransformRequest::class

默认中间件规则表示每个字段都应该去除空白字符,如果为空则设置为 null

'middleware_rules' => [
    '**' => 'trim|return_null_if_empty',
]

规则不必应用于所有字段;如果需要,可以在中间件中针对特定字段进行操作

'middleware_rules' => [
    'postcode'  => 'uppercase',
    'email'     => 'lowercase',
]

以上配置下,通过中间件发送的每个请求的邮编和电子邮件字段将受到影响,但所有其他字段将保持不变。

在项目中使用多个转换中间件可能很有用:为此,将 laravel-transformer/src/Middleware/TransformRequest.php 复制到您的项目的 App/Http/Middleware 目录中,并根据需要重命名/编辑。每个新的中间件都必须在内核中注册。

贡献

欢迎贡献,并将得到充分认可。我们将通过拉取请求接受贡献。

  • 使用PSR-2编码标准。
  • 添加测试,如果您不确定如何操作,请咨询。
  • 在行为变更中记录文档更改,包括readme.md。

测试

我们使用 PHPUnit 和出色的 orchestral/testbench

使用PHPUnit运行测试: vendor/bin/phpunit