iqomp / formatter
对象格式化和数据填充器
Requires (Dev)
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
格式化单个对象。此方法接受以下参数
string $format
在全局配置中定义的格式名称。object $object
要格式化的对象。array $options
传递给每个格式类型处理器的额外选项列表。
请参见上面的用法示例。
static function formatApply(array $formats, array $objects, array $options=[], string $askey=null): ?array
将一系列规则应用于对象而无需在全局配置中注册。此方法接受以下参数
array $formats
要应用于对象的格式类型列表。array $objects
要格式化的对象列表。array $options
传递给每个格式类型处理器的额外选项列表。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 )
将单个格式化类型应用于值。内部,所有上述方法都使用此方法来为每个对象的属性应用格式化类型。此方法接受以下参数
string $type
要应用于值的格式类型。$value
要格式化的值。string $field
从对象中获取此值的字段名称。object $object
从中获取值的原始对象。mixed $format
字段格式配置的值。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
,则不会更改任何数据。
此方法以下列参数调用
array $values
所有正在格式化或根据处理器配置的其他对象属性的索引数组。string $field
正在处理的字段名称。array $objects
正在处理的所有对象。数组 $format
被应用于字段的格式配置。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
,则不会更改任何数据。
此方法以下列参数调用
mixed $value
正在格式化的对象属性。string $field
正在处理的字段名称。object $object
正在处理的对象。数组 $format
被应用于字段的格式配置。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' ] ] ] ];
上述选项将返回仅具有 id
和 created_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
和!in
,expected
配置期望一个数组。
类型对象
某些对象格式类型将对象属性的值转换为内部对象。该对象实现\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;
获取属性safe
和clean
将返回新的对象~\Text
。属性safe
返回原始值的htmlspecialschars($, ENT_QUOTES)
。属性clean
返回仅包含字符a-zA-Z0-9
的文本。
代码检查器
composer lint