dominionenterprises / filter
Requires
- php: ^7.3 || ^8.0
- traderinteractive/exceptions: ^2.0
- traderinteractive/filter-arrays: ^4.1
- traderinteractive/filter-bools: ^4.0
- traderinteractive/filter-dates: ^4.0
- traderinteractive/filter-floats: ^4.0
- traderinteractive/filter-ints: ^4.0
- traderinteractive/filter-strings: ^4.0
Requires (Dev)
- phpunit/phpunit: ^9.0
- squizlabs/php_codesniffer: ^3.2
- symfony/yaml: ^3.4
This package is auto-updated.
Last update: 2024-09-04 17:15:13 UTC
README
用于验证正确数据并执行典型数据修改的过滤实现。
特性
- 紧凑、易读的规范
- 支持使用任何PHP可调用函数进行过滤,例如
- 匿名函数
- 类函数
- 内置函数
- 可选/必需支持,字段和全局级别
- 默认支持
- 链式过滤
- 可选返回未知字段
- 过滤别名支持
组件
此包是一个部分元包,聚合以下组件
- traderinteractive/filter-arrays
- traderinteractive/filter-bools
- traderinteractive/filter-dates
- traderinteractive/filter-floats
- traderinteractive/filter-ints
- traderinteractive/filter-strings
示例
class AppendFilter { public function filter($value, $extraArg) { return $value . $extraArg; } } $appendFilter = new AppendFilter(); $trimFunc = function($val) { return trim($val); }; list($status, $result, $error, $unknowns) = TraderInteractive\Filterer::filter( [ 'field one' => [[$trimFunc], ['substr', 0, 3], [[$appendFilter, 'filter'], 'boo']], 'field two' => ['required' => true, ['floatval']], 'field three' => ['required' => false, ['float']], 'field four' => ['required' => true, 'default' => 1, ['uint']], ], ['field one' => ' abcd', 'field two' => '3.14'] ); var_dump($status); var_dump($result); var_dump($error); var_dump($unknowns);
打印
bool(true) array(3) { 'field one' => string(6) "abcboo" 'field two' => double(3.14) 'field four' => int(1) } NULL array(0) { }
Composer
要作为本地、项目级依赖项添加库,请使用Composer!只需将traderinteractive/filter
依赖项添加到您的项目的composer.json
文件中,如下所示
composer require traderinteractive/filter
文档
在源代码中找到,请查看!
Filterer
此库的核心是一个Filterer
类,它可以验证数组的结构并通过过滤器映射数据。此行为由要应用的不同过滤器的规范和一些附加选项定义。
规范
规范是一个键 => 过滤器规范对的数组。
键定义了数组中的已知字段。数组中不在规范中的任何字段都被视为“未知”字段,并且可能因allowUnknowns
选项的值而导致验证失败。
单个字段的过滤器规范也是一个数组。它可以包含预定义的过滤器选项。
字段的其他规范是应用到此字段的过滤器。
过滤器中的第一个元素是要运行的过滤器。这可以是传递is_callable
的任何内容(例如,'trim'
或[$object, 'method']
),或者它可以是我们的预定义别名之一(例如,'float'
)。
过滤器中的其余元素是过滤器的额外参数(被过滤的值始终是第一个参数)。
过滤器规范可以包含任何数量的过滤器,每个过滤器的结果作为输入传递到下一个过滤器。最后一个过滤器的结果设置为结果数组。
上面的示例应该有助于阐明所有这些。
Filterer 选项
allowUnknowns
摘要
允许在未经过滤的输入中存在不在过滤器规范中的元素。
类型
- bool
默认值
默认值是false
常量
TraderInteractive\FiltererOptions::ALLOW_UNKNOWNS
示例
$options = [ TraderInteractive\FiltererOptions::ALLOW_UNKNOWNS => true, ]; $filterer = new TraderInteractive\Filterer($specification, $options);
defaultRequired
摘要
标志,用于定义过滤器规范中所有元素默认必需的行为。如果为true
,则规范中的所有元素都是必需的,除非它们已设置必需的过滤器选项。
类型
- bool
默认值
默认值是false
常量
TraderInteractive\FiltererOptions::DEFAULT_REQUIRED
示例
$options = [ TraderInteractive\FiltererOptions::DEFAULT_REQUIRED => true, ]; $filterer = new TraderInteractive\Filterer($specification, $options);
responseType
摘要
指定了 Filterer::filter 方法返回的响应类型。可以是 数组
或 \TraderInteractive\FilterResponse
类型
- 字符串
默认值
默认值是 数组
常量
TraderInteractive\FiltererOptions::RESPONSE_TYPE
示例
$options = [ TraderInteractive\FiltererOptions::RESPONSE_TYPE => \TraderInteractive\FilterResponse::class, ]; $filterer = new TraderInteractive\Filterer($specification, $options);
过滤器选项
必需
摘要
定义该字段是否为数组的必需元素。此值将覆盖全局过滤器指定的 defaultRequired
选项。
类型
- bool
默认值
默认值取决于 defaultRequired
过滤器选项。
常量
TraderInteractive\FilterOptions::IS_REQUIRED
示例
$specificaton = [ 'id' => [TraderInteractive\FilterOptions::IS_REQUIRED => true, ['uint']], ];
默认
摘要
定义如果没有提供默认值,该字段的默认值是什么。具有默认值的字段将确保包含在结果中。required
值不影响 default
行为。
类型
- 字符串
默认值
此选项没有默认值。
常量
TraderInteractive\FilterOptions::DEFAULT_VALUE
示例
$specificaton = [ 'subscribe' => [TraderInteractive\FilterOptions::DEFAULT_VALUE => true, ['bool']], 'status' => [TraderInteractive\FilterOptions::DEFAULT_VALUE => 'A', ['string', false, 1, 1]], ];
错误
摘要
定义如果值过滤失败,将返回的自定义错误消息。在错误字符串中,可以使用 {value}
作为过滤失败的值的占位符。
类型
- 字符串
默认值
此选项没有默认值。
常量
TraderInteractive\FilterOptions::CUSTOM_ERROR
示例
$specificaton = [ 'price' => [ TraderInteractive\FilterOptions::CUSTOM_ERROR => 'Price {value} was not between 0 and 100', ['uint', false, 0, 100], ], ];
conflictsWith
摘要
定义与给定字段冲突的任何输入字段。当输入一个字段或另一个字段但不两者同时输入时使用。
类型
- 字符串
默认值
此选项没有默认值。
常量
TraderInteractive\FilterOptions::CONFLICTS_WITH
示例
$specification = [ 'id' => [ TraderInteractive\FilterOptions::CONFLICTS_WITH => 'code', [['uint']], ], 'code' => [ TraderInteractive\FilterOptions::CONFLICTS_WITH => 'id', [['string']], ], ];
uses
摘要
指定应用作字段过滤器规范一部分的输入值数组。
类型
- 字符串[]
默认值
此选项的默认值是一个空数组。
常量
TraderInteractive\FilterOptions::USES
示例
$specification = [ 'base' => [ [['float']], ], 'exponent' => [ ['uint'], [ TraderInteractive\FilterOptions::USES => 'base', 'pow', ], ], ];
指数过滤器规范将使用提供的值调用 PHP 函数 pow()
和过滤后的 base
的结果。
throwOnError
摘要
如果为真,Filterer 将在过滤值时抛出任何捕获到的异常,而不是在过滤器响应中返回错误。
类型
- 布尔值
默认值
此选项的默认值是 false
常量
TraderInteractive\FilterOptions::THROW_ON_ERROR
示例
$idFilter = function ($id) : int { if (!is_int($id)) { throw new NotFoundException("id '{$id}' was not found"); } return $id; }; $specification = [ 'id' => [ \TraderInteractive\FilterOptions::THROW_ON_ERROR => true, [$idFilter], ], ];
如果输入中给出的 id
值不是整数,Filterer::execute() 将抛出 NotFoundException
returnOnNull
摘要
标志,如果结果值为 null
则中断过滤器链。对于非空字段非常有用,如果值不为空,则需要额外的过滤。
类型
- 布尔值
默认值
此选项的默认值是 false
常量
TraderInteractive\FilterOptions::RETURN_ON_NULL
示例
$validCodes = ['A', 'I', 'X']; $specification = [ 'code' => [ \TraderInteractive\FilterOptions::RETURN_ON_NULL => true, ['string', true], ['strtoupper'], ['in', $validCodes], ], ];
如果 code
值为 null
,则过滤后的结果值将为 null
。否则,值必须是 $validCode
之一。
包含的过滤器
当然,任何函数都可能有潜力用作过滤器,但我们包括一些有用的过滤器,并带有别名以处理常见情况。
Filterer::ofScalars
在过滤器器中以 ofScalars
别名,此过滤器验证参数是否为数组(可能是空的),其中每个元素都通过给定的过滤器(以与 Filterer::filter
相同的格式给出)。
以下检查 $value
是否为无符号整数的数组。
$value = \TraderInteractive\Filter\Filterer::ofScalars($value, [['uint']]);
Filterer::ofArrays
在过滤器器中以 ofArrays
别名,此过滤器验证参数是否为数组(可能是空的),其中每个元素都是数组,并通过给定的过滤器(以与 Filterer::filter
相同的格式给出)。
以下检查 $value
是否为具有 id
键的项的数组,其值为数字。不允许其他键。例如,以下输入是有效的:[['id' => '1'], ['id' => '2']]
。
$value = \TraderInteractive\Filter\Filterer::ofArrays($value, ['id' => [['uint']]]);
Filterer::ofArray
在过滤器器中以 ofArray
别名,此过滤器验证参数是否为数组,并符合给定的规范。这是 Filterer::filter
的反转版本,允许测试嵌套关联数组。
Arrays::copy
在过滤器器中以 array-copy
别名,此过滤器使用提供的目标键映射将源数组中的值复制到目标数组。
示例用法
$specification = ['field' => [['array-copy', ['FOO_VALUE' => 'foo', 'BAR_VALUE' => 'bar']]]]; $filterer = new TraderInteractive\Filterer($specification); $input = ['foo' => 123, 'bar' => 'abc']; $result = $filterer->execute($input); assert(['field' => ['FOO_VALUE' => 123, 'BAR_VALUE' => 'abc']], $result->filteredValue);
Arrays::copyEach
在过滤器器中以 array-copy-each
别名,此过滤器使用提供的目标键映射将源数组中的每个数组的值复制到目标数组。
示例用法
$specification = ['field' => [['array-copy-each', ['FOO_VALUE' => 'foo', 'BAR_VALUE' => 'bar']]]]; $filterer = new TraderInteractive\Filterer($specification); $input = [ ['foo' => 123, 'bar' => 'abc'], ['foo' => 456, 'bar' => 'def'], ]; $result = $filterer->execute($input); assert(['field' => [['FOO_VALUE' => 123, 'BAR_VALUE' => 'abc'], ['FOO_VALUE' => 456, 'BAR_VALUE' => 'def']]], $result->filteredValue);
Arrays::implode
在过滤器器中以 implode
别名,此过滤器是 implode
的包装,以确保正确的参数顺序。
$sepcification = ['field' => [['array'],['implode', ',']]]; $filterer = new TraderInteractive\Filterer($specification); $input = [ 'field' => ['lastname', 'email', 'phone'], ]; $result = $filterer->execute($input); assert(['field' => 'lastname,email,phone'], $result->filteredValue);
Arrays::in
在过滤器中以 in
别名,此过滤器是 in_array
的包装,包括对严格相等性测试的支持。
以下对 $value
进行了严格检查,以与3个接受值进行对比。
\TraderInteractive\Filter\Arrays::in($value, ['a', 'b', 'c']);
Arrays::arrayize
在过滤器中以 arrayize
别名,此过滤器如果输入是数组,则返回原始输入,否则返回包裹在数组中的输入。如果原始输入为null,则返回空数组。
$value = \TraderInteractive\Filter\Arrays::arrayize('a string value'); assert($value === ['a string value']);
Arrays::filter
在过滤器中以 array
别名,此过滤器验证参数是否为数组,并检查数组的长度是否在范围内。默认范围是1+,所以空数组默认失败。
以下检查 $value
是否为一个恰好有3个元素的数组。
\TraderInteractive\Filter\Arrays::filter($value, 3, 3);
Arrays::flatten
在过滤器中以 flatten
别名,此过滤器将多维数组扁平化为单维数组。值顺序将保持不变,但键本身将不会。例如
$value = \TraderInteractive\Filter\Arrays::flatten([[1, 2], [3, [4, 5]]]); assert($value === [1, 2, 3, 4, 5]);
Arrays::pad
在过滤器中以 array-pad
别名,此过滤器使用指定值填充数组到指定长度。可以选择性地向前或向后填充数组。
示例用法
$specification = ['field' => [['array-pad', 5, 0, Arrays::ARRAY_PAD_LEFT]]], $filterer = new TraderInteractive\Filterer($specification); $input = [2, 4, 6]; $result = $filterer->execute($input); assert(['field' => [0, 0, 2, 4, 6]], $result->filteredValue);
Booleans::filter
在过滤器中以 bool
别名,此过滤器验证参数是否为布尔值或映射到布尔值的字符串。第二个参数可以设置为 true
以允许通过null值而不引发错误(它们将保持null并不会转换为false)。最后几个参数是字符串列表,分别表示true值和false值。默认情况下,字符串 "true" 和 "false" 映射到它们的布尔对应值。
以下示例将 $value
转换为布尔值,允许字符串 "on" 和 "of"。
$enabled = \TraderInteractive\Filter\Booleans::filter($value, false, ['on'], ['off']);
Booleans::convert
在过滤器中以 bool-convert
别名,此过滤器将给定的布尔值转换为提供的true或false条件。默认返回值是字符串 'true' 和 'false'
以下将布尔值 $value
转换为 'yes' 或 'no'
$answer = \TraderInteractive\Filter\Booleans::convert($value, 'yes', 'no');
Floats/Ints/UnsignedInt::filter
分别以 float
、int
和 uint
别名,这些过滤器验证参数是否为正确的数字类型,并允许进行范围检查。每个的第二个参数可以设置为 true
以允许通过null值而不引发错误(它们将保持null并不会转换为false)。接下来两个参数是最小和最大范围,可以用来限制允许数字的范围。
非数字字符串将验证失败,数字字符串将被转换。
浮点参数有一个额外的参数可以设置为 true
以将整数转换为浮点数。如果没有这个参数,整数将验证失败。
以下检查 $value
是否为一个介于1和100之间的整数(包括1和100),并返回该整数(如果它是一个字符串,则进行转换)。
$value = \TraderInteractive\Filter\UnsignedInt::filter($value, false, 1, 100);
Strings::filter
在过滤器中以 string
别名,此过滤器验证参数是否为字符串。第二个参数可以设置为 true
以允许通过null值而不引发错误(它们将保持null并不会转换为false)。最后几个参数指定字符串的长度范围。默认范围是1+,所以空字符串默认失败。
以下检查 $value
是否为一个非空字符串。
\TraderInteractive\Filter\Strings::filter($value);
Strings::concat
在过滤器中以 concat
别名,此过滤器连接给定的 $value、$prefix 和 $suffix 并返回结果字符串。
$value = \TraderInteractive\Filter\Strings::concat('middle', 'begining_', '_end'); assert($value === 'begining_middle_end');
Strings::explode
在过滤器中以 explode
别名,此过滤器实际上是内置 explode
方法的包装,将值放在顺序的第一位,以便与 Filterer
一起使用。它还默认使用 ,
作为分隔符。例如
$value = \TraderInteractive\Filter\Strings::explode('abc,def,ghi'); assert($value === ['abc', 'def', 'ghi']);
Strings::stripTags
在过滤器中别名为strip-tags
,此过滤器本质上是对内置的strip_tags
函数的包装。然而,与原生函数不同,当stripTags方法接收到null值时,它将返回null。
$value = \TraderInteractive\Filter\Strings::stripTags('A string with <p>tags</p>'); assert($value === 'a string with tags');
Strings::translate
在过滤器中别名为translate
,此过滤器接受一个字符串值,并返回其在给定的$valueMap中找到的翻译值。
$value = \TraderInteractive\Filter\Strings::tranlsate('bar', ['foo' => 'translated to bar', 'bar' => 'translated to foo']); assert($value === 'translated to foo');
Url::filter
在过滤器中别名为url
,此过滤器验证参数是否为符合RFC2396的URL字符串。第二个参数可以设置为true
以允许null值通过而不会产生错误(它们将保持null状态,不会被转换为false)。
以下检查$value
是否是一个URL。
\TraderInteractive\Filter\Url::filter($value);
Closures::filter
在过滤器中别名为closure
,此过滤器验证参数是否是闭包函数。
以下检查$closureMethod
是否是闭包。
$closureMethod = function () { doSomething(); }; \TraderInteractive\Filter\Closures::filter($closureMethod);
Email::filter
在过滤器中别名为email
,此过滤器验证参数是否是电子邮件。
以下检查$value
是否是电子邮件。
\TraderInteractive\Filter\Email::filter($value);
DateTime::filter
在过滤器中别名为date
,这将值作为\DateTime
对象进行过滤。值可以是任何符合PHP的有效日期/时间格式的字符串。
以下检查$value
是否是日期/时间。
$dateTime = \TraderInteractive\Filter\DateTime::filter('2014-02-04T11:55:00-0500');
DateTime::format
在过滤器中别名为date-format
,这将给定的`\DateTime`值根据给定的格式转换为字符串。
以下为给定的`\DateTime` $value
返回格式化的字符串。
$formatted = \TraderInteractive\Filter\DateTime::format($value, 'Y-m-d H:i:s');
DateTimeZone::filter
在过滤器中别名为date
,这将值作为\DateTimeZone
对象进行过滤。值可以是任何受支持的时区名称。
以下检查$value
是否是时区。
$timezone = \TraderInteractive\Filter\DateTimeZone::filter('America/New_York');
Json::validate
在过滤器中别名为json
,检查JSON是否有效并返回原始值。
以下确保$value
是有效的JSON。
$value = \TraderInteractive\Filter\Json::validate('{"foo": "bar"}');
Json::parse
在过滤器中别名为json-decode
,检查JSON是否有效并返回解码的结果。
以下解码给定的值并返回结果。
$value = \TraderInteractive\Filter\Json::parse('{"foo": "bar"}'); assert($value === ['foo' => 'bar']);
PhoneFilter::filter
在过滤器中别名为phone
,这将给定的值作为电话进行过滤,以指定的格式返回电话。
以下将给定的字符串过滤为格式化的电话字符串。
$value = \TraderInteractive\Filter\PhoneFilter::filter('234.567.8901', false, '({area}) {exchange}-{station}'); assert($value === '(234) 567-8901');
TimeOfDayFilter::filter
在过滤器中别名为time-of-day
,这将给定的字符串值过滤为HH:MM:SS
格式的每天时间。
以下确保$value
是有效的HH:MM:SS
格式字符串。
$value = \TraderInteractive\Filter\TimeOfDayFilter::filter('12:15:23'); assert($value === '12:15:23');
XmlFilter::filter
在过滤器中别名为xml
,这将确保给定的字符串值是有效的XML,并返回原始值。
以下确保给定的字符串是有效的XML。
$value = <<<XML <?xml version="1.0"?> <books> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developers Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies</description> </book> </books> XML; $xml = \TraderInteractive\Filter\XmlFilter::filter($value);
XmlFilter::extract
在过滤器中别名为xml-extract
,这将确保给定的字符串值是有效的XML,然后提取并返回给定xpath中找到的元素。
以下确保给定的字符串是有效的XML,并返回第一本书的标题元素。
$value = <<<XML <?xml version="1.0"?> <books> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developers Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies</description> </book> </books> XML; $xpath = "/books/book[@id='bk101']/title"; $titleXml = \TraderInteractive\Filter\XmlFilter::extract($value, $xpath); assert($titleXml === '<title>XML Developers Guide</title>');
XmlFilter::validate
在过滤器中别名为xml-validate
,这将确保给定的字符串值是有效的XML,并确认符合给定的XSD文件。原始值将被返回。
以下确保给定的字符串是有效的XML,并匹配books.xsd。
$value = <<<XML <?xml version="1.0"?> <books> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developers Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies</description> </book> </books> XML; $xml = \TraderInteractive\Filter\XmlFilter::validate($value, 'books.xsd');
Contact
开发者可以通过以下方式联系:
项目构建
使用代码检出,在您的PATH中获取Composer并运行
./build.php
此外,还有一个基于docker的fig配置,可以在docker容器内执行构建。这是一种构建应用程序的简单方法
fig run build
有关我们构建过程的更多信息,请参阅我们的贡献指南。