iqomp/formatter

对象格式化和数据填充器

2.2.0 2021-07-15 06:25 UTC

This package is auto-updated.

Last update: 2024-09-15 13:22:24 UTC


README

这是一个库,根据格式配置将单个或多个对象格式化以满足您的需求。在将对象(从数据库)发送到客户端或查看之前,这是您需要的库。

安装

composer require iqomp/formatter

发布配置

php bin/hyperf.php vendor:publish iqomp/formatter

配置

您应该为数据库中保存的每个对象定义一个格式。请按照以下步骤创建新的对象格式配置。

将您的对象格式化配置添加到文件 config/autoload/formatter.php 中,内容如下

<?php

return [
    'formats' => [
        '/format-name/' => [
            '/field-name/' => [
                'type' => '/field-trans-type/',
                '@finalize' => '/field-trans-type/'
            ],
            // ...
        ],
        'my-object' => [
            'id' => [
                'type' => 'number',
                '@finalize' => 'format'
            ],
            'name' => [
                'type' => 'text'
            ],
            'created_at' => [
                'type' => 'date',
                'timezone' => 'UTC'
            ]
        ]
    ]
];

用法

此模块创建了一个新的全局类,您可以使用它来格式化您的对象,类 Iqomp\Formatter\Formatter 是您从这个模块中需要的唯一类。

<?php

use Iqomp\Formatter\Formatter;

// formatting single object
$object = Formatter::format('my-object', $object, $options);

// formatting many object
$objects = Formatter::formatMany('my-object', $objects, $options);

方法

Iqomp\Formatter\Formatter 定义了一些可以在任何地方使用的方法

static function format(string $format, object $object, array $options=[]): ?object

格式化单个对象。此方法接受以下参数

  1. string $format 在全局配置中定义的格式名称。
  2. object $object 要格式化的对象。
  3. array $options 传递给每个格式类型处理器的额外选项列表。

请参见上面的用法示例。

static function formatApply(array $formats, array $objects, array $options=[], string $askey=null): ?array

将一系列规则应用于对象而无需在全局配置中注册。此方法接受以下参数

  1. array $formats 要应用于对象的格式类型列表。
  2. array $objects 要格式化的对象列表。
  3. array $options 传递给每个格式类型处理器的额外选项列表。
  4. string $askey 要用作格式结果数组键的对象属性。如果此字段未设置,则返回索引数组。

static function formatMany(string $format, array $objects, array $options=[], string $askey=null): array

format 相同,但用于多个对象。请参见上面的方法以了解参数。

static function typeApply(string $type, $value, string $field, object $object, $format, $options )

将单个格式化类型应用于值。内部,所有上述方法都使用此方法来为每个对象的属性应用格式化类型。此方法接受以下参数

  1. string $type 要应用于值的格式类型。
  2. $value 要格式化的值。
  3. string $field 从对象中获取此值的字段名称。
  4. object $object 从中获取值的原始对象。
  5. mixed $format 字段格式配置的值。
  6. mixed $options 传递给格式类型处理器的选项。

请参见下面的示例。

<?php

use Iqomp\Formatter\Formattter;

$object = (object)[
    'id' => 1,
    'name' => 'User Name',
    'created' => '2010-01-01 12:22:22'
];

$value = Formatter::applyType('number', $object->id, 'id', $object, [], []);

自定义处理器

在相同的情况下,您可能会发现我们提供的格式类型不够或不符合您的条件。在这种情况下,您可能更喜欢创建自己的格式类型处理器。

此模块知道两种类型的格式类型处理器。非集体和集体行动。

集体

如果您的处理器是集体类型,格式化器将收集所有对象的属性并一次性调用处理器。如果您的处理器需要调用外部资源(如数据库或curl),则此类型很好。

此方法将被调用如下

$res = Class::method($values, $field, $objects, $format, $options);

此方法的返回值预期为 oldvalue => newvalue 对。

如果此方法返回 null,则不会更改任何数据。

此方法以下列参数调用

  1. array $values 所有正在格式化或根据处理器配置的其他对象属性的索引数组。
  2. string $field 正在处理的字段名称。
  3. array $objects 正在处理的所有对象。
  4. 数组 $format 被应用于字段的格式配置。
  5. mixed $options 由格式化调用者发送的格式选项。

以下是一个集体处理器的示例

    // ...
    public static function addPrefix($values, $field, $objects, $format, $options)
    {
        $result = [];
        $prefix = $options ?? '_';

        foreach ($values as $val) {
            $result[$val] = $prefix . $val;
        }

        return $result;
    }
    // ...

非集体

这是常见的格式类型。本模块中所有格式类型处理器都使用此类型。

此方法将被调用如下

$res = Class::method($value, $field, $object, $format, $options)

如果此方法返回 null,则不会更改任何数据。

此方法以下列参数调用

  1. mixed $value 正在格式化的对象属性。
  2. string $field 正在处理的字段名称。
  3. object $object 正在处理的对象。
  4. 数组 $format 被应用于字段的格式配置。
  5. mixed $options 由格式化调用者发送的格式选项。

以下是非集体处理器的示例

    // ...
    public static function addPrefix($value, $field, $object, $format, $options)
    {
        $prefix = $options ?? '_';

        return $prefix . $val;
    }
    // ...

创建自定义处理器

按照以下步骤创建新的格式类型处理器

创建类型处理器

创建一个新的类来处理对象属性

<?php

namespace MyModule\Formatter;

class MyHandler
{
    protected static function getPrefix($format, $options): string
    {
        $prefix = '_'; // default

        // get prefix from user formatter config:
        // 'formats' => [
        //      '/name/' => [
        //          '/field/' => [
        //              'type' => 'prefix',
        //              'prefix' => '_'
        //          ]
        //      ]
        //  ]
        if (isset($format['prefix'])) {
            $prefix = $format['prefix'];
        }

        // get prefix from user provided options:
        // $res = Formatter::format('/name/', $/obj/, [
        //     '/field/' => '_'
        // ])
        if ($options) {
            $prefix = '_';
        }

        return $prefix;
    }

    // the config:
    // 'handlers' => [
    //      'prefix-one' => [
    //          'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixSingle',
    //          'collective' => false
    //      ]
    // ]
    public static function addPrefixSingle($value, $field, $object, $format, $options)
    {
        $prefix = self::getPrefix($format, $options);

        return $prefix .  $value;
    }

    // the config
    // 'handlers' => [
    //      'prefix-two' => [
    //          'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixCollective',
    //          'collective' => true,
    //          'field' => null
    //      ]
    // ]
    public static function addPrefixCollective($values, $field, $objects, $format, $options)
    {
        $prefix = self::getPrefix($format, $options);

        $result = [];
        foreach ($values as $value) {
            $result[$value] = $prefix . $value;
        }

        return $result;
    }

    // the config
    // 'handlers' => [
    //      'prefix-three' => [
    //          'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixById',
    //          'collective' => true,
    //          'field' => 'id'
    //      ]
    //  ]
    public static function addPrefixById($values, $field, $objects, $format, $options)
    {
        $prefix = self::getPrefix($format, $options);

        $result = [];
        foreach ($objects as $object) {
            $result[$object->id] = $prefix . $object->$field;
        }

        return $result;
    }

    // the config
    // 'handlers' => [
    //      'prefix-four' => [
    //          'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixByMD5',
    //          'collective' => '_MD5_',
    //          'field' => null
    //      ]
    //  ]
    public static function addPrefixByMD5($values, $field, $objects, $format, $options)
    {
        $prefix = self::getPrefix($format, $options);

        $result = [];
        foreach ($values as $value) {
            $hash = md5($value);
            $result[$hash] = $prefix . $value;
        }

        return $result;
    }
}

在类型处理器中返回 null 将不会修改对象属性。

注册处理器配置

在你的模块中创建一个新的文件名为 ConfigProvider,并在 __invoke 公共方法中返回以下数组

// ...
    return [
        'formatter' => [
            'handlers' => [
                'prefix-one' => [
                     'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixSingle',
                     'collective' => false
                 ],
                 'prefix-two' => [
                     'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixCollective',
                     'collective' => true,
                     'field' => null
                 ],
                 'prefix-three' => [
                     'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixById',
                     'collective' => true,
                     'field' => 'id'
                 ],
                 'prefix-four' => [
                     'handler' => 'MyModule\\Formatter\\MyHandler::addPrefixByMD5',
                     'collective' => '_MD5_',
                     'field' => null
                 ]
            ]
        ]
    ];
/// ...

然后,更新你的模块 composer.json 文件以注册新的配置,如下所示

    "extra": {
        "hyperf": {
            "config": "Vendor\\Module\\ConfigProvider"
        }
    }

特殊选项

这是在某些条件下可以帮助你的某些特殊格式选项。

@default

如果值是假的,则设置属性的默认值。

return [
    'formats' => [
        '/my-object/' => [
            '/field/' => [
                'type' => 'text',
                '@default' => 'Hello World'
            ]
        ]
    ]
];

@rest

将当前格式选项应用于没有格式类型选项的所有对象属性。

return [
    'formats' => [
        '/my-object/' => [
            '@rest' => [
                'type' => 'delete'
            ],
            'id' => [
                'type' => 'number',
            ],
            'created_at' => [
                'type' => 'date'
            ]
        ]
    ]
];

上述选项将返回仅具有 idcreated_at 属性的对象。其余对象属性将应用 'type' => 'delete' 选项。

@clone

将其他对象属性值克隆到当前新属性中,克隆操作在将格式类型应用于属性之前完成。

return [
    'formats' => [
        '/my-object/' => [
            'user_id' => [
                'type' => 'number'
            ],
            'user' => [
                '@clone' => 'user_id',
                'type' => 'std-id'
            ]
        ]
    ]
];

属性 user 将克隆未格式化的属性 user_id 的值,并将格式类型 std-id 应用到 user 属性。

@rename

重命名当前对象属性名。重命名操作在对象格式化之后完成。

return [
    'user_id' => [
        '@rename' => 'user',
        'type' => 'std-id'
    ]
];

上述选项将对象属性 user_id 重命名为 user

@finalize

在所有对象属性格式化之后,再次调用格式类型到对象属性。此格式类型将在将格式结果返回给调用者之前应用。

    // ...
    '/field/' => [
        'type' => 'number',
        '@finalize' => 'format'
    ]
    // ...

格式类型

以下是本模块迄今为止定义的所有已知格式类型

bool/boolean

将值转换为布尔类型。

    // ...
    '/field/' => [
        'type' => 'bool' // 'boolean'
    ]
    // ...

clone

有条件地克隆其他对象属性的值,与特殊选项 @clone 的区别在于此类型不格式化克隆的值,并且此类型只能克隆对象属性的部分子属性。

它可以有条件地使用其他格式类型转换值。

    // ...
    '/field/' => [
        'type' => 'clone',
        'source' => [
            'field' => 'user.name.first',
            'type' => 'text' // optional. convert the value to type text
        ]
    ]
    // ...

上述选项将创建一个新的对象属性 /field/,其数据来自 $object->user->name->first。并将值转换为类型 text。属性 /field/ 的最终值现在是 Iqomp\Formatter\Object\Text 对象。

要创建具有多个对象属性值的属性,请使用 sources 选项。

    // ...
    '/field/' => [
        'type' => 'clone',
        'sources' => [
            'name' => [
                'field' => 'user.name.first',
                'type' => 'text'
            ],
            'bdate' => [
                'field' => 'birthdate',
                'type' => 'date'
            ]
        ]
    ]
    // ...

上述选项将创建一个名为 /field/ 的新对象属性,其类型为对象。属性 name 来自 $object->user->name->first 并将其值转换为类型 text。第二个属性是 bdate,它来自 $object->birthdate 并将其值转换为类型 date

custom

使用其他处理器修改对象属性值。

    // ...
    '/field/' => [
        'type' => 'custom',
        'handler' => 'Class::method'
    ]
    // ...

回调将获得与格式类型处理器非集体参数完全相同的参数。

date

将值转换为 Iqomp\Formatter\Object\DateTime 对象。如果没有设置时区,它将回退到 php xdefault 时区。

    // ...
    '/field/' => [
        'type' => 'date',
        'timezone' => 'UTC' // optional
    ]
    // ...

有关此对象的详细信息,请参见以下内容。

delete

删除对象属性。

    // ...
    '/field/' => [
        'type' => 'delete'
    ]
    // ...

embed

将值转换为 Iqomp\Formatter\Object\Embed。这是生成流行视频服务(如 YouTube 等)的嵌入 HTML 代码的对象。

    // ...
    '/field/' => [
        'type' => 'embed'
    ]
    // ...

interval

将值转换为 Iqomp\Formatter\Object\Interval

    // ...
    '/field/' => [
        'type' => 'interval'
    ]
    // ...

有关此对象的更多信息,请参见以下内容。

multiple-text

将值转换为使用相同分隔符的Iqomp\Formatter\Object\Text数组。它将原始值string转换为对象类型的text数组。

    // ...
    '/field/' => [
        'type' => 'multiple-text',
        'separator' => ',' // 'json'
    ]
    // ...

如果separator的值为null,则使用PHP_EOL作为分隔符。如果是'json',则使用json_decode来分隔值。

数字

将值转换为Iqomp\Formatter\Object\Number

    // ...
    '/field/' => [
        'type' => 'number',
        'decimal' => 2 // optional
    ]
    // ...

如果未设置小数,则最终值将为int,如果值大于0,则将为float。请参阅以下关于此对象的信息。

文本

将值转换为Iqomp\Formatter\Object\Text

    // ...
    '/field/' => [
        'type' => 'text'
    ]
    // ...

有关此对象的更多信息,请参见以下内容。

JSON

使用json_decode将JSON字符串的值转换为数组/对象。如果存在format属性,则将使用提供的格式格式化解析的值。

    // ...
    '/field/' => [
        'type' => 'json',
        'format' => 'my-other-object'
    ]
    // ...

连接

将文本和对象属性值组合起来填充当前属性。要获取对象属性的值,请向数组成员的值添加前缀$

    // ...
    '/field/' => [
        'type' => 'join',
        'fields' => ['My', 'name', 'is', '$user.name.first'],
        'separator' => ' '
    ]
    // ...

上面的示例将创建一个文本My name is (:name),其中占位符(:name)的值将从$object->user->name->first中获取。

重命名

重命名对象属性名。

    // ...
    '/field/' => [
        'type' => 'rename',
        'to' => '/new-field/'
    ]
    // ...

std-id

将值转换为Iqomp\Formatter\Object\Std,这是一个只有一个属性为id的对象。

    // ...
    '/field/' => [
        'type' => 'std-id'
    ]
    // ...

如果您使用格式类型std-id对对象属性进行JSON编码,则它将类似于{"id":val}

开关

允许您根据某些对象属性的值将格式类型应用于对象属性的一种格式类型。

    // ...
    '/field/' => [
        'type' => 'switch',
        'case' => [
            '/name-1/' => [
                'field' => '/object-property-name/',
                'operator' => '=',
                'expected' => 1,
                'result' => [
                    'type' => 'number'
                ]
            ],
            '/name-2' => [
                'field' => '/object-property-name/',
                'operator' => '>',
                'expected' => 2,
                'result' => [
                    'type' => 'text'
                ]
            ]
        ]
    ]
    // ...

根据上述配置,如果条件匹配,则将应用上述配置的result配置的对象属性/field/的值。

如果object->/object-property-name/的值为1,则当前属性将使用'type' => 'number'进行格式化。或者如果值大于2,则将使用'type' => 'text'进行格式化。

目前已知的操作符包括=!=><>=<=in!in。对于操作符in!inexpected配置期望一个数组。

类型对象

某些对象格式类型将对象属性的值转换为内部对象。该对象实现\JsonSerializable,使其可以进行json_encode

以下是目前已知的对象列表

Iqomp\Formatter\Object\DateTime

扩展了自定义属性的\DateTime的对象。

$val->format(string $format);
$val->timezone;
$val->time;
$val->value;
$val->{DateTime functions}(...);

Iqomp\Formatter\Object\Embed

识别并生成流行视频服务URL的嵌入式HTML脚本的对象。

$val->url;
$val->provider;
$val->html;

它将为__toString()json_encode返回最终URL。

Iqomp\Formatter\Object\Interval

处理间隔字符串的对象。

$val->format(string $format);
$val->interval();
$val->time;
$val->value;
$val->DateTime;
$val->DateInterval;

Iqomp\Formatter\Object\Number

与数字一起工作的对象。

$val->value;
$val->format([$decimal=0, [$dec_separator=',', [$tho_separator='.']]]);

Iqomp\Formatter\Object\Std

只有一个属性id的简单对象,该属性取自属性的原始值。

$val->id;

Iqomp\Formatter\Object\Text

与文本一起工作的对象。

$val->chars(int $len);
$val->words(int $len);
$val->safe;
$val->clean;
$val->value;

获取属性safeclean将返回新的对象~\Text。属性safe返回原始值的htmlspecialschars($, ENT_QUOTES)。属性clean返回仅包含字符a-zA-Z0-9 的文本。

代码检查器

composer lint