mcustiel / php-simple-request
php-simple-request 是一个用于简化请求验证和过滤的最简库
Requires
- php: >=5.5
- doctrine/annotations: ^1.2
- psr/cache: ^1.0.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^1.11
- pdepend/pdepend: ^2.0.6
- phing/phing: ^2.12.0
- phploc/phploc: ^2.1.1
- phpmd/phpmd: ^2.3.2
- phpunit/phpunit: ^4.8.9
- satooshi/php-coveralls: ~1.0
- sebastian/phpcpd: ^2.0.2
- squizlabs/php_codesniffer: ^2.3.4
- symfony/cache: dev-master
This package is auto-updated.
Last update: 2023-07-19 06:35:55 UTC
README
php-simple-request 是一个旨在简化请求验证和过滤的库,它从请求数据生成对象表示形式。
该库背后的理念是设计代表应用程序接收到的请求的对象,并使用 php-simple-request 将请求数据映射到这些对象并对接收到的数据进行清理。为此,库提供了一套注释来指定对请求数据要执行的过滤器和服务。
该库通过使用缓存系统来保存由读取注释生成的解析器类,从而优化性能。
目录
安装
Composer
该项目已发布在 Packagist 上,因此您只需将其添加到 composer.json 中的依赖项即可
"require": { // ... "mcustiel/php-simple-request": "*" }
如果您想直接访问此存储库,将以下内容添加到 composer.json 中应该足够
{ "repositories": [ { "type": "vcs", "url": "https://github.com/mcustiel/php-simple-request" } ], "require": { "mcustiel/php-simple-request": "dev-master" } }
或者,只需下载发行版并将其包含在路径中。
如何使用它?
定义表示请求的对象
首先,您必须定义代表您期望应用程序接收到的请求的类。此类的设置方法将被 php-simple-request 用于将请求中获得的值写入对象。
namespace Your\Namespace; class PersonRequest { private $firstName; private $lastName; private $age; // getters and setters (setters are required by the library) }
然后,您可以指定要应用于每个字段的过滤器
namespace Your\Namespace; use Mcustiel\SimpleRequest\Annotation\Filter\Trim; use Mcustiel\SimpleRequest\Annotation\Filter\UpperCase; class PersonRequest { /** * @Trim */ private $firstName; /** * @Trim * @UpperCase */ private $lastName; private $age; // getters and setters (setters are required by the library) }
以及您要为每个属性值运行的验证
namespace Your\Namespace; use Mcustiel\SimpleRequest\Annotation\Filter\Trim; use Mcustiel\SimpleRequest\Annotation\Filter\UpperCase; use Mcustiel\SimpleRequest\Annotation\Validator\NotEmpty; use Mcustiel\SimpleRequest\Annotation\Validator\MaxLength; use Mcustiel\SimpleRequest\Annotation\Validator\Integer; class PersonRequest { /** * @Trim * @NotEmpty */ private $firstName; /** * @Trim * @UpperCase * @NotEmpty * @MaxLength(32) */ private $lastName; /** * @Integer */ private $age; // getters and setters (setters are required by the library) }
注意:php-simple-request 首先执行过滤器,然后执行验证。
解析请求并获取对象表示
要解析请求并将其转换为对象的表示形式,只需使用RequestBuilder对象接收请求(请求中的字段名必须与您定义的类中的字段名相同)。您必须使用数组或\stdClass类型的对象调用parseRequest方法。请看以下示例
use Mcustiel\SimpleRequest\RequestBuilder; use Your\Namespace\PersonRequest; use Mcustiel\SimpleRequest\Exceptions\InvalidRequestException; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Mcustiel\SimpleRequest\ParserGenerator; use Mcustiel\SimpleRequest\Services\PhpReflectionService; use Mcustiel\SimpleRequest\Services\DoctrineAnnotationService; use Mcustiel\SimpleRequest\Strategies\AnnotationParserFactory; use Mcustiel\SimpleRequest\FirstErrorRequestParser; $requestBuilder = new RequestBuilder( new FilesystemAdapter(), new ParserGenerator( new DoctrineAnnotationService(), new AnnotationParserFactory(), new PhpReflectionService ) ); try { $personRequest = $requestBuilder->parseRequest($_POST, PersonRequest::class); } catch (InvalidRequestException $e) { die("The request is invalid: " . $e->getMessage()); } // Now you can use the validated and filtered personRequest to access the requestData.
如果您的请求作为POST的子数组接收,只需指定键
$personRequest = $requestBuilder->parseRequest($_POST['person'], PersonRequest::class);
它也可以用于一些REST json请求
$request = file_get_contents('php://input'); $personRequest = $requestBuilder->parseRequest(json_decode($request, true), PersonRequest::class, , new FirstErrorRequestParser());
以前的行为在验证中发现错误时会抛出异常。存在另一种行为,您可以获取一个验证错误列表,每个无效字段一个。要激活此替代行为,您必须像这样在调用RequestBuilder::parseRequest
时指定它
use Mcustiel\SimpleRequest\RequestBuilder; use Your\Namespace\PersonRequest; use Mcustiel\SimpleRequest\Exceptions\InvalidRequestException; use Mcustiel\SimpleRequest\AllErrorsRequestParser; $requestBuilder = new RequestBuilder(); try { $personRequest = $requestBuilder->parseRequest( $_POST, PersonRequest::class, RequestBuilder::RETURN_ALL_ERRORS_IN_EXCEPTION ); } catch (InvalidRequestException $e) { $listOfErrors = $e->getErrors(); // This call returns only one error for the default behavior } // Now you can use the validated and filtered personRequest to access the requestData.
注意:InvalidRequestException::getErrors()在默认行为中也可用,它返回一个仅包含一个错误的数组。
子对象
php-simple-request还允许您使用ParseAs注解指定解析属性值的类。最好通过示例来了解它
假设我们想创建一个Couple类,它包含两个类型为Person的对象,代表夫妇的成员。要指定属性必须解析为Person,我们使用ParseAs。
use Mcustiel\SimpleRequest\Annotation as SRA; class CoupleRequest { /** * @SRA\Validator\DateTimeFormat("Y-m-d") */ private $togetherSince; /** * @SRA\ParseAs("\Your\Namespace\PersonRequest") */ private $person1; /** * @SRA\ParseAs("\Your\Namespace\PersonRequest") */ private $person2; //... Getters and setters (setters are required by the library) }
php-simple-request将自动将请求中接收到的fields person1和person2的字段值转换为PersonRequest类型。
注意:如果属性具有ParseAs注解以及验证和过滤器,php-simple-request将首先执行parseAs,然后按常规执行过滤器和验证。
对象数组
如果您打算解析的不是对象,而是对象数组,您可以使用数组表示法告诉php-simple-request这样做,将类名作为数组的第一个元素
try {
$persons = $requestBuilder->parseRequest(
$_POST['form_data'],
[PersonRequest::class],
RequestBuilder::RETURN_ALL_ERRORS_IN_EXCEPTION
);
// Now $persons is an array containing PersonRequest objects.
} catch (InvalidRequestException $e) {
$listOfErrors = $e->getErrors(); // This call returns only one error for the default behavior
}
缓存
由于请求类定义使用注解来指定过滤器和验证器,因此解析所有这些注解和使用反射时会产生大量开销。为了避免这种开销,php-simple-request支持使用PSR-6 Cache。只需将实现作为第一个参数传递给创建RequestBuilder
对象的调用
$requestBuilder = new RequestBuilder( new AnyPsr6PoolAdapter(), new ParserGenerator(new AnnotationReader(), new AnnotationParserFactory()) );
您可以为测试目的传递一个NullObject实现。
过滤器
首字母大写
此过滤器将所有字符串字符转换为小写,但将其第一个字符(转换为大写)。此注解接受一个布尔指定值,用于定义是否只将字符串中第一个单词的首字母或所有单词的首字母大写。
/** * @Capitalize */ private $name; // Will convert, for instance, mariano to Mariano. /** * @Capitalize(true) */ private $fullName; // Will convert, for instance, mariano custiel to Mariano Custiel.
自定义过滤器
这是一个特殊的过滤器注解,允许您指定自己的过滤器类并使用它来过滤字段中的值。它接受两个参数
- value:指定器。
- class:您的自定义过滤器类(它必须实现Mcustiel\SimpleRequest\Interfaces\FilterInterface
/** * @CustomFilter(class="Vendor\\App\\MyFilters\\MyFilter", value="yourSpecifier") */ private $somethingHardToFilter; // Will call Vendor\\App\\MyFilters\\MyFilter::filter($value) using "yourSpecifier".
默认值
当接收到的值为null或空字符串时设置默认值。
/** * @DefaultValue("I am a default value") */ private $thisCanHaveADefault;
小写
小写过滤器将给定字符串中的所有字符转换为小写。
RegexReplace
使用正则表达式模式作为搜索来执行字符串中的替换。它接受两个参数
- pattern: 要搜索的正则表达式。
- replacement: 匹配的替换文本。
/** * @RegexReplace(pattern="/[^a-z0-9_]/i", replacement="_") */ private $onlyAlnumAndUnderscores; // Will replace all non alphanumeric characters with underscores.
StringReplace
使用字符串模式作为搜索来执行字符串中的替换。它接受两个参数
- pattern: 要搜索的字符串。
- replacement: 匹配的替换文本。
注意: 此方法使用 str_replace 内部,您可以通过将模式设置为数组等方式利用它。[查看 str_replace 规范](https://php.ac.cn/manual/en/function.str-replace.php)。
/** * @StringReplace(pattern="E", replacement="3") */ private $whyAmIChangingThis; // Will replace all non E with 3.
ToFloat
此过滤器只是强制将接收到的值转换为浮点数。
ToInteger
与 Float 类似,强制将接收到的值转换为整数。
Trim
从两端修剪字符串。
UpperCase
将给定字符串中的所有字符转换为大写。
Validators
带有 (*) 标记的验证器行为类似于 json-schema 定义的验证器。请参阅:[JSON Schema 定义](https://json-schema.fullstack.org.cn/latest/json-schema-validation.html)和[理解 JSON Schema](https://github.com/mcustiel/php-simple-request/blob/HEAD/spacetelescope.github.io/understanding-json-schema/)。
AllOf*
此验证器接收一个验证器列表作为参数,并检查它们是否都匹配给定的值。您可以通过为该属性添加多个 Valitor 注解来获得相同的行为。
示例
/** * @AllOf({@Integer, @Minimum(0), @Maximum(100)}) */ private $percentage; // Will match an integer between 0 and 100.
Alpha
此验证器检查字符串中的所有字符是否在 A-Z 或 a-z 的范围内。
示例
/** * @Alpha */ private $onlyLetters; // Will match a string containing only letters.
AlphaNumeric
此验证器检查字符串中的所有字符是否在 A-Z、a-z 或 0-9 的范围内。
示例
/** * @AlphaNumeric */ private $lettersAndNumbers; // Will match a string containing only alphanumeric characters.
AnyOf*
此验证器接收一个验证器列表作为参数,并检查是否至少有一个验证器验证给定的值。
示例
/** * @AnyOf({@Integer, @IPV6}) */ private $integerOrIpv6; // Will match an integer or an IPV6.
CustomValidator
这是一个特殊的验证器注解,允许您指定自己的验证器类,并使用它来验证字段中的值。它接受两个参数
- value:指定器。
- class: 这是您的自定义过滤器类(它必须实现 Mcustiel\SimpleRequest\Interfaces\ValidatorInterface
示例
/** * @CustomValidator(class="Vendor\\App\\MyValidators\\MyValidator", value="yourSpecifier") */ private $somethingHardToCheck; // Will call Vendor\\App\\MyValidators\\MyValidator::validate($value) using "yourSpecifier".
DateTime*
此验证器检查给定的字符串是否为日期,并且其格式与\DateTime::RFC3339兼容(Y-m-d\TH:i:sP)
示例
/** * @DateTime */ private $dateTime; // Matches 2005-08-15T15:52:01+00:00
默认指定符值: \DateTime::ISO8601
DateTimeFormat
此验证器检查给定的字符串是否为日期,并且其格式与指定的日期格式兼容。作为注解值的指定格式必须与php方法\DateTime::createFromFormat兼容。
示例
/** * @DateTimeFormat("M d, Y") */ private $dayOfBirth; // Matches Oct 17, 1981
默认指定符值: \DateTime::ISO8601
定义*
此验证器是CustomValidator的别名。
此验证器检查给定的值是否为包含电子邮件的字符串。此注解不需要指定值指定符。
示例
/** * @Email */ private $email;
Enum*
此验证器检查给定的值是否在指定的值集合中。
示例
/** * @Enum('value1', 'value2', 'value3') */ private $enum; // Will match the strings value1, value2 or value3.
ExclusiveMaximum*
此验证器检查给定的值是否小于指定的值。
示例
/** * @ExclusiveMaximum(0) */ private $negativeReals; // Will match any number < 0.
ExclusiveMinimum*
此验证器检查给定的值是否大于指定的值。
示例
/** * @ExclusiveMinimum(0) */ private $age; // Will match any number > 0.
Hexa
此验证器检查给定的值是否为仅包含十六进制字符的字符串(范围0-9,a-f,A-F)。
示例
/** * @Hexa */ private $htmlColor;
Hostname
检查值是否为主机名。
示例
/** * @Hostname */ private $responseDomain;
TypeFloat
此验证器检查给定的值是否为浮点数。在此注解中可以指定布尔修饰符,表示值必须是严格的浮点数,还是整数也可以作为浮点数进行验证。
示例
/** * @Float */ private $meters; // accepts 1, 1.1, etc. /** * @Float(true) */ private $meters; // accepts 1.0, 1.1, etc.
默认指定符值: false,表示整数作为浮点数进行验证
TypeInteger
此验证器检查给定的值是否为数字且为整数。它期望一个布尔修饰符,表示整数格式如1.0、2.0等是否应被视为整数进行验证。默认严格值:true,表示不接受浮点数格式。
示例
/** * @Integer */ private $seconds; // accepts 1, 2, -3, 0, etc.
/** * @Integer(false) */ private $majorVersion; // accepts 1, 2.0, 3, etc.
IPV4
此验证器检查给定值是否为有效的IPv4。它不期望任何修饰符。
示例
/** * @IPV4 */ private $ip; // accepts 0.0.0.0, 255.255.255.255, etc.
IPv6
此验证器检查给定值是否为有效的IPv6。它不期望任何修饰符。
示例
/** * @IPV6 */ private $ip; // accepts ::A000:A000, A000::A000, A000::A000::, 2001:0000:3238:DFE1:63:0000:0000:FEFB, etc.
项目*
此验证器检查给定数组中的每个元素是否与其相应索引中的指定验证器匹配。它期望两个参数:items和additionalItems。Items包含数组的验证,它可以是一个验证器(在这种情况下,每个元素都必须匹配它)或验证器的数组(在这种情况下,每个元素都必须匹配同一位置中的验证器);其默认值是一个空数组。AdditionalItems可以是布尔值或验证器;如果是布尔值true,则不在同一位置具有验证器的items将不会进行检查;如果为false,则不会接受在同一位置没有验证器的值;如果是验证器,则所有在同一位置没有验证器的项目都必须匹配它。有关详细和良好的描述,请参阅前面提到的关于JSON Schema的文档。默认指定器值:
- items = []
- additionalItems = true
/** * @Items(items=@Integer, additionalItems=true) */ private $arrayOfInt; // accepts Arrays of int of any size.
MAC地址*
验证值是否为指定MAC地址的字符串。
示例
/** * @MacAddress */ private $mac;
最大值*
此验证器检查给定值是否小于或等于指定值。
示例
/** * @Maximum(0) */ private $negativeRealsOrZero; // Will match any number <= 0.
最大项目数*
此验证器检查字段是否为数组,并且其项目数量等于或小于指定值。指定值必须是一个大于0的整数。字段必须是一个数组。
示例
/** * @MaxItems(3) */ private $stoogesOnScreen; // accepts [], ['curly'], ['curly', 'larry'] and ['curly', 'larry', 'moe'].
最大长度*
此验证器检查字段的长度是否等于或小于指定值。指定值必须是一个整数。字段必须是一个字符串。
示例
/** * @MaxLength(4) */ private $pin; // accepts empty string, 1, 12, 123 and 1234.
默认指定器值 255
最大属性数*
此注释验证给定的数组或stdClass包含最多指定的项目或属性数。它与MaxItems类似。
示例
/** * @MaxProperties(3) */ private $stoogesOnScreen; // accepts (stdClass) [], (stdClass)['stooge1'->'curly'], (array)['stooge1'=>'curly', 'stooge2'=>'larry'], ['curly', 'larry', 'moe'].
最小值*
此验证器检查给定值是否大于或等于指定值。
示例
/** * @Minimum(-273) */ private $temperatureInCelsius; // Will match any number >= -273.
最小项目数*
此验证器检查字段是否为数组,并且其项目数量等于或大于指定值。指定值必须是一个大于0的整数。字段必须是一个数组。
示例
/** * @MinItems(2) */ private $players; // accepts ['alice', 'bob'], ['a' => 'alice', 'b' => 'bob'], ['alice', 'bob', 'carol'].
最小长度*
此验证器检查字段的长度是否等于或大于指定值。指定值必须是一个整数。字段可以是字符串或数组。
示例
/** * @MinLength(8) */ private $password; // accepts 'password', 'password1', 'password1234' and all those very secure passwords.
默认指定器值 0
最小属性数量*
此验证器检查字段是否为数组或stdClass,并且其元素数量等于或大于指定值。指定值必须是一个大于0的整数。
示例
/** * @MinProperties(2) */ private $players; // accepts ['a' => 'alice', 'b' => 'bob'], ['alice', 'bob', 'carol'], stdclass(a->'alice', 'b'->'bob');
是...的倍数*
验证接收到的值是否为指定数字的倍数。
示例
/** * @MultipleOf(2) */ private $evenNumber; // accepts 8, 20, 100, etc.
不*(Not)
检查值是否不符合指定的验证器。
示例
/** * @Not(@MultipleOf(2)) */ private $oddNumber; // accepts 3, 15, 97, etc.
NotEmpty
此验证器检查字段是否不为空。内部,此验证器使用php的empty,因此功能完全相同。它不期望任何修饰符。
示例
/** * @NotEmpty */ private $password; // accepts 1, 'A', ['a'], etc.
默认指定器值 0
NotNull
此验证器检查字段是否不为null,也可以用来检查字段是否存在于请求中。只有在您想检查值是否存在且接受字段中的空值时,才应使用此函数;如果不接受空值,则应使用NotEmpty验证器,该验证器也检查值是否为null。它不期望任何修饰符。
示例
/** * @NotNull */ private $mandatoryField; // accepts '', 0, [], 1, 'A', ['a'], etc.
OneOf*
此验证器接收一个验证器列表作为参数,并检查它们中恰好有一个验证给定的值。
示例
/** * @AnyOf(@Integer, @IPV6) */ private $integerOrIpv6; // Will match an integer 'xor' an IPV6.
Pattern*
RegExp验证器的别名。
Properties*
类似于items,但它与stdClass类型或关联数组的对象一起工作。它通过stdClass的属性或关联数组中的项运行验证器列表,使用属性名称或模式。请参阅前面提到的关于json-schema的文档。
默认指定器值
- properties = []
- patternProperties = []
- additionalProperties = true
示例
/** * @Items(properties={"name", @NotEmpty, "age", @Numeric}, additionalProperties=true) */ private $person; // accepts Arrays or objects containing a not empty name property and a numeric age property. Can contain other properties (because additionalProperties is true)
注意:此注释被添加为类似json-schema的注释。请注意,在大多数情况下,最好通过ParseAs注释创建子对象。
RegExp
此验证器检查字段是否与给定的正则表达式匹配。
示例
/** * @RegExp("/[a-z]*/i") */ private $onlyAlpha; // accepts '', 'a', 'A', 'ab', etc.
必填*
此验证器检查一个类型为stdClass或关联数组的对象是否包含指定的键列表。
示例
/** * @Required({"name", "age", "sex"}) */ private $person; // accepts ['name' => 'Alice', 'age' => 28, 'sex' => 'f', 'lastName' => 'Smith' ]
TwitterAccount
此验证器检查字段是否包含Twitter账户。
示例
/** * @TwitterAccount */ private $twitterAccount; // accepts '@user', '@user_name_1', etc.
类型*
验证接收到的值是否为指定的类型。指定的类型必须是json-schema定义的类型之一:'array'(数组), 'object'(对象), 'integer'(整数), 'number'(数字), 'string'(字符串), 'boolean'(布尔值), 'null'(空)。
示例
/** * @Type("array") */ private $iCanOnlyBeAnArray;
UniqueItems*
验证接收到的值是否为数组,且包含所有唯一值。
示例
/** * @UniqueItems */ private $noRepeatedValues;
Uri*
此验证器检查字段是否包含有效的URL。
示例
/** * @Uri */ private $webpage; // accepts 'localhost', 'www.server.com', 'http://www.webserver.com/page.php?t=1#anchor', etc