tobento / service-sanitizer
轻松清理数据。
1.0.0
2021-06-30 15:20 UTC
Requires
- php: >=8.0
- tobento/service-collection: ^1.0
- tobento/service-dater: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.0
README
清理服务提供了一种轻松清理用户输入的方法。
目录
入门
运行以下命令添加清理服务的最新版本。
composer require tobento/service-sanitizer
要求
- PHP 8.0 或更高版本
亮点
- 框架无关,适用于任何项目
- 解耦设计
- 可扩展
- 支持嵌套值
- 自定义过滤器解析
简单示例
以下是一个如何使用清理服务的简单示例。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); // sanitize a single value. $sanitized = $sanitizer->sanitizing('<p>lorem ipsum</p>', 'cast:string|stripTags|ucwords'); // sanitize multiple values. $sanitized = $sanitizer->sanitize( [ 'name' => 'Thomas', 'birthday' => '1982-10-30', 'description' => 'Lorem ipsum', ], [ 'name' => 'cast:string', 'birthday' => 'date:Y-m-d:d.m.Y', 'description' => 'cast:string|stripTags', ] );
文档
清理
单个值
轻松清理单个值。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitizing('<p>lorem ipsum</p>', 'stripTags|ucwords'); var_dump($sanitized); // string(11) "Lorem Ipsum"
多个值
清理多个值。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitize( [ 'name' => 'Thomas', 'birthday' => '1982-10-30', 'description' => 'Lorem ipsum', ], [ 'name' => 'cast:string', 'birthday' => 'date:Y-m-d:d.m.Y', 'description' => 'cast:string|stripTags', ] ); /*Array ( [name] => Thomas [birthday] => 30.10.1982 [description] => Lorem ipsum )*/
嵌套值
如果传入的值包含“嵌套”数据,您可以在过滤器中使用“点”语法指定这些属性
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitize( [ 'title' => 'Title', 'author' => [ 'name' => 'Tom', 'description' => 'Lorem ipsum', ], ], [ 'name' => 'cast:string', 'author.name' => 'cast:string', 'author.description' => 'cast:string|stripTags', ] );
使用数组作为过滤器
根据 FiltersParsers 实现,您可能需要以数组的形式设置过滤器,因为某些参数可能需要解析符号,如“:”。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitizing( '1982-10-30T19:30', [ 'date' => ['Y-m-d', 'Y.m.d H:i'] ] ); var_dump($sanitized); // string(11) "30.10.1982 19:30"
严格清理
如果使用严格清理,即使数据不存在,也会应用过滤器。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitize( [ 'name' => 'Thomas', ], [ 'age' => 'cast:int:21', ], strictSanitation: true, ); /*Array ( [name] => Thomas [age] => 21 )*/
仅清理数据
有时可能需要仅获取清理后的数据
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitize( [ 'name' => 'Thomas', ], [ 'age' => 'cast:int:21', ], strictSanitation: true, returnSanitizedOnly: true, ); /*Array ( [age] => 21 )*/ $sanitized = $sanitizer->sanitize( [ 'name' => 'Thomas', ], [ 'age' => 'cast:int:21', ], strictSanitation: false, returnSanitizedOnly: true, ); /*Array()*/
过滤
默认过滤器
以下是一些开箱即用的过滤器
⚠️ 一些过滤器(如 stripTags)如果类型不是字符串,则返回原始值。因此,您可能需要添加 cast:string 过滤器。
自定义默认过滤器
如果您想设置自己的默认过滤器,可以按以下方式操作
use Tobento\Service\Sanitizer\Sanitizer; use Tobento\Service\Sanitizer\SanitizerInterface; use Tobento\Service\Sanitizer\FiltersInterface; class CustomDefaultFilters implements FiltersInterface { /** * Add the filters to the sanitizer. * * @param SanitizerInterface $sanitizer * @return void */ public function addFilters(SanitizerInterface $sanitizer): void { $sanitizer->addFilter('cast', new \Tobento\Service\Sanitizer\Filter\Cast()); } } $sanitizer = new Sanitizer(new CustomDefaultFilters());
添加过滤器
您可以通过以下方式添加自己的过滤器。如果相同的过滤器键已经存在,它将覆盖该过滤器。
use Tobento\Service\Sanitizer\Sanitizer; use Tobento\Service\Sanitizer\FilterInterface; $sanitizer = new Sanitizer(); // By a callable. $sanitizer->addFilter('trim', function(mixed $value, array $parameters): mixed { return is_string($value) ? trim($value) : $value; }); // By a class implementing the FilterInterface. class TrimFilter implements FilterInterface { /** * Apply the filter. * * @param mixed $value The value to sanitize * @param array $parameters The parameters set on the sanitation 'filter:foo:bar' * * @throws FilterException If filter cannot handle sanitation * * @return mixed The sanitized value */ public function apply(mixed $value, array $parameters = []): mixed { return is_string($value) ? trim($value) : $value; } } $sanitizer->addFilter('trim', new TrimFilter());
关于 FilterIf 的说明
"filterIf" 过滤器仅在值匹配给定的条件时应用过滤器。
use Tobento\Service\Sanitizer\Sanitizer; $sanitizer = new Sanitizer(); $sanitized = $sanitizer->sanitize( [ 'country' => 'CH', 'phone' => '+41 76 123 45 67', ], [ // filter phone only if country value is "CH" 'phone' => 'filterIf:country:CH|digit', ], returnSanitizedOnly: true, ); var_dump($sanitized); // array(1) { ["phone"]=> string(11) "41761234567" }
您可以通过扩展 FilterIf 类轻松添加更多 FilterIf 条件
use Tobento\Service\Sanitizer\Sanitizer; use Tobento\Service\Sanitizer\Filter\FilterIf; use Tobento\Service\Collection\Collection; // Filter only if the attributes defined are present. class FilterIfPresent extends FilterIf { /** * Apply the filter. * * @param mixed $value The value to sanitize * @param array $parameters The parameters set on the sanitation 'filter:foo:bar' * * @throws FilterException If filter cannot handle sanitation * * @return mixed The sanitized value */ public function apply(mixed $value, array $parameters = []): mixed { // extract value and data. [$value, $data] = $value; if (! $data instanceof Collection) { return false; } return $data->has($parameters); } } $sanitizer = new Sanitizer(); $sanitizer->addFilter('filterIfPresent', new FilterIfPresent()); $sanitized = $sanitizer->sanitize( [ 'country' => 'CH', 'locale' => 'de-CH', 'phone' => '+41 76 123 45 67', ], [ // filter phone only if country and locale is present. 'phone' => 'filterIfPresent:country:locale|digit', ] ); /*Array ( [country] => CH [locale] => de-CH [phone] => 41761234567 )*/
解析过滤器
您可以更改清理时解析过滤器的行为。
use Tobento\Service\Sanitizer\Sanitizer; use Tobento\Service\Sanitizer\FiltersParserInterface; use Tobento\Service\Sanitizer\ParsedFilter; class CustomParser implements FiltersParserInterface { /** * Parses the filters. * * @param string|array * @return array The parsed filters [ParsedFilter, ...] */ public function parse(string|array $filters): array { // do your parsing strategy $parsedFilters = []; return $parsedFilters; } } $sanitizer = new Sanitizer(filtersParser: new CustomParser());