From 6c24f6eeb4068a7d51264eed958706b200db1469 Mon Sep 17 00:00:00 2001 From: vijay Date: Mon, 27 Sep 2021 11:31:47 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=E5=92=8C=E4=B8=BB=E8=A6=81=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .phpstorm.meta.php | 10 ++++ src/main/Annotation/NumberScope.php | 61 ++++++++++++++++++++++++ src/main/Annotation/Pattern.php | 45 ++++++++++++++++++ src/main/Annotation/Size.php | 64 +++++++++++++++++++++++++ src/main/Base/ValidAnnoInterface.php | 32 +++++++++++++ src/main/Utils/AnnotationUtils.php | 71 ++++++++++++++++++++++++++++ src/main/Validor/Validator.php | 55 +++++++++++++++++++++ 7 files changed, 338 insertions(+) create mode 100644 .phpstorm.meta.php create mode 100644 src/main/Annotation/NumberScope.php create mode 100644 src/main/Annotation/Pattern.php create mode 100644 src/main/Annotation/Size.php create mode 100644 src/main/Base/ValidAnnoInterface.php create mode 100644 src/main/Utils/AnnotationUtils.php create mode 100644 src/main/Validor/Validator.php diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000..aa3d148 --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,10 @@ + "$1[]"])); +} + +# end of file diff --git a/src/main/Annotation/NumberScope.php b/src/main/Annotation/NumberScope.php new file mode 100644 index 0000000..c68b725 --- /dev/null +++ b/src/main/Annotation/NumberScope.php @@ -0,0 +1,61 @@ +message)) { + return $this->message; + } + $list = []; + if ($this->max !== null) { + $list[] = "不能大于 {$this->max}"; + } + if ($this->min !== null) { + $list[] = "不能小于 {$this->min}"; + } + return "对象属性 {$reflection->class}::{$reflection->name} " . implode("且", $list); + } + + /** + * @inheritDoc + */ + public function isValid(mixed $value): bool + { + if ($this->max !== null && $value > $this->max) { + return false; + } + if ($this->min !== null && $value < $this->min) { + return false; + } + return true; + } +} + +# end of file diff --git a/src/main/Annotation/Pattern.php b/src/main/Annotation/Pattern.php new file mode 100644 index 0000000..b963012 --- /dev/null +++ b/src/main/Annotation/Pattern.php @@ -0,0 +1,45 @@ +message)) { + return $this->message; + } + return "对象属性 {$reflection->class}::{$reflection->name} 不匹配要求的正则表达式 {$this->pattern}"; + } + + /** + * @inheritDoc + */ + public function isValid(mixed $value): bool + { + return boolval(preg_match($this->pattern, strval($value))); + } +} + +# end of file diff --git a/src/main/Annotation/Size.php b/src/main/Annotation/Size.php new file mode 100644 index 0000000..1212596 --- /dev/null +++ b/src/main/Annotation/Size.php @@ -0,0 +1,64 @@ +message)) { + return $this->message; + } + $list = []; + if ($this->sizeMax !== null) { + $list[] = "不能大于 {$this->sizeMax}"; + } + if ($this->sizeMin !== null) { + $list[] = "不能小于 {$this->sizeMin}"; + } + return "对象属性 {$reflection->class}::{$reflection->name} 的 size " . implode("且", $list); + } + + /** + * @inheritDoc + */ + public function isValid(mixed $value): bool + { + if (is_array($value) || is_object($value)) { + $size = count($value); + } else { + $size = strlen(strval($value)); + } + + if ($this->sizeMax !== null && $size > $this->sizeMax) { + return false; + } + if ($this->sizeMin !== null && $size < $this->sizeMin) { + return false; + } + return true; + } +} + +# end of file diff --git a/src/main/Base/ValidAnnoInterface.php b/src/main/Base/ValidAnnoInterface.php new file mode 100644 index 0000000..301b27e --- /dev/null +++ b/src/main/Base/ValidAnnoInterface.php @@ -0,0 +1,32 @@ +getAttributes(); + $list = []; + foreach ($attrs as $attr) { + if (!class_exists($attr->getName())) { + continue; + } + if ($className && !is_a($attr->getName(), $className, true)) { + continue; + } + $list[] = $attr->newInstance(); + } + return $list; + } + + /** + * - + * @param ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection + * 反射 + * @param ?string $className 注解要求的类名 + * @psalm-param class-string $className + * @psalm-return ?T 注解对象 + * @template T + */ + public static function getAttrObj( + ReflectionProperty|ReflectionClass|ReflectionParameter|ReflectionFunctionAbstract|ReflectionClassConstant $reflection, + string $className = null + ): ?object { + $attrs = $reflection->getAttributes(); + foreach ($attrs as $attr) { + if (!class_exists($attr->getName())) { + continue; + } + if ($className && !is_a($attr->getName(), $className, true)) { + continue; + } + return $attr->newInstance(); + } + return null; + } +} + +# end of file diff --git a/src/main/Validor/Validator.php b/src/main/Validor/Validator.php new file mode 100644 index 0000000..6213d7e --- /dev/null +++ b/src/main/Validor/Validator.php @@ -0,0 +1,55 @@ +getProperties($filter) as $property) { + $allow = $property->isPublic(); + if (!$allow) { + $property->setAccessible(true); + } + if ($property->isInitialized($object)) { + $value = $property->getValue($object); + } else { + $value = null; + } + if (!$allow) { + $property->setAccessible(false); + } + foreach (AnnotationUtils::getAttrObjs($property, ValidAnnoInterface::class) as $attrObj) { + if (!$attrObj->isValid($value)) { + continue; + } + $msg = $attrObj->errorMessage($property, $value); + if (strlen($msg)) { + throw new CheckErrorException($msg); + } + } + } + } +} + +# end of file -- Gitee From 8e9f4a52adef08de05a2cf96d32532db9e719062 Mon Sep 17 00:00:00 2001 From: vijay Date: Mon, 27 Sep 2021 14:48:42 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=A0=A1=E9=AA=8C=E7=9A=84=E6=8E=A5=E5=8F=A3=20?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E8=8C=83=E5=9B=B4=E6=A3=80=E6=9F=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/Annotation/NumberScope.php | 6 ++- src/main/Annotation/Pattern.php | 8 ++- src/main/Annotation/Size.php | 10 +++- src/main/Utils/ReflectionUtils.php | 38 +++++++++++++ src/main/ValidationInterface.php | 16 ++++-- src/main/Validor/Validator.php | 83 ++++++++++++++++++++++------- src/test/Cases/ValidatorTest.php | 68 +++++++++++++++++++++++ src/test/Helper/DemoPojo.php | 32 +++++++++++ src/test/Helper/SimpleBuilder.php | 32 +++++++++++ 9 files changed, 265 insertions(+), 28 deletions(-) create mode 100644 src/main/Utils/ReflectionUtils.php create mode 100644 src/test/Cases/ValidatorTest.php create mode 100644 src/test/Helper/DemoPojo.php create mode 100644 src/test/Helper/SimpleBuilder.php diff --git a/src/main/Annotation/NumberScope.php b/src/main/Annotation/NumberScope.php index c68b725..e82df9e 100644 --- a/src/main/Annotation/NumberScope.php +++ b/src/main/Annotation/NumberScope.php @@ -6,6 +6,7 @@ namespace DreamCat\ObjectValid\Annotation; use Attribute; use DreamCat\ObjectValid\Base\ValidAnnoInterface; +use DreamCat\ObjectValid\Utils\ReflectionUtils; use JetBrains\PhpStorm\Immutable; use ReflectionParameter; use ReflectionProperty; @@ -40,7 +41,7 @@ class NumberScope implements ValidAnnoInterface if ($this->min !== null) { $list[] = "不能小于 {$this->min}"; } - return "对象属性 {$reflection->class}::{$reflection->name} " . implode("且", $list); + return ReflectionUtils::getReflectDesc($reflection) . " " . implode(" 且", $list); } /** @@ -48,6 +49,9 @@ class NumberScope implements ValidAnnoInterface */ public function isValid(mixed $value): bool { + if ($value === null) { + return true; + } if ($this->max !== null && $value > $this->max) { return false; } diff --git a/src/main/Annotation/Pattern.php b/src/main/Annotation/Pattern.php index b963012..61354ea 100644 --- a/src/main/Annotation/Pattern.php +++ b/src/main/Annotation/Pattern.php @@ -6,6 +6,7 @@ namespace DreamCat\ObjectValid\Annotation; use Attribute; use DreamCat\ObjectValid\Base\ValidAnnoInterface; +use DreamCat\ObjectValid\Utils\ReflectionUtils; use JetBrains\PhpStorm\Immutable; use ReflectionParameter; use ReflectionProperty; @@ -18,7 +19,7 @@ use ReflectionProperty; #[Immutable] class Pattern implements ValidAnnoInterface { - public function __construct(private string $pattern, private string $message) + public function __construct(private string $pattern, private ?string $message = null) { } @@ -30,7 +31,7 @@ class Pattern implements ValidAnnoInterface if (!is_null($this->message)) { return $this->message; } - return "对象属性 {$reflection->class}::{$reflection->name} 不匹配要求的正则表达式 {$this->pattern}"; + return ReflectionUtils::getReflectDesc($reflection) . " 不匹配要求的正则表达式 {$this->pattern}"; } /** @@ -38,6 +39,9 @@ class Pattern implements ValidAnnoInterface */ public function isValid(mixed $value): bool { + if ($value === null) { + return true; + } return boolval(preg_match($this->pattern, strval($value))); } } diff --git a/src/main/Annotation/Size.php b/src/main/Annotation/Size.php index 1212596..4208af1 100644 --- a/src/main/Annotation/Size.php +++ b/src/main/Annotation/Size.php @@ -18,8 +18,11 @@ use ReflectionProperty; #[Immutable] class Size implements ValidAnnoInterface { - public function __construct(private int $sizeMin, private int $sizeMax, private string $message) - { + public function __construct( + private ?int $sizeMin = null, + private ?int $sizeMax = null, + private ?string $message = null + ) { } /** @@ -45,6 +48,9 @@ class Size implements ValidAnnoInterface */ public function isValid(mixed $value): bool { + if ($value === null) { + return true; + } if (is_array($value) || is_object($value)) { $size = count($value); } else { diff --git a/src/main/Utils/ReflectionUtils.php b/src/main/Utils/ReflectionUtils.php new file mode 100644 index 0000000..72b2127 --- /dev/null +++ b/src/main/Utils/ReflectionUtils.php @@ -0,0 +1,38 @@ +name)) { + $name = $reflector->name; + } elseif (method_exists($reflector, "getName")) { + $name = $reflector->getName(); + } else { + $name = strval($reflector); + } + if (isset($reflector->class)) { + $name = "{$reflector->class}::{$name}"; + } + return $name; + } +} + +# end of file diff --git a/src/main/ValidationInterface.php b/src/main/ValidationInterface.php index 4f32bb9..261cb73 100644 --- a/src/main/ValidationInterface.php +++ b/src/main/ValidationInterface.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace DreamCat\ObjectValid; use DreamCat\ObjectValid\Exception\CheckErrorException; +use ReflectionParameter; /** * 对象属性检查接口 @@ -14,11 +15,20 @@ interface ValidationInterface { /** * 检查数据是否合格 - * @param object $object + * @param object $object 要检查的对象 * @return void - * @throws CheckErrorException + * @throws CheckErrorException 检查不通过时抛出异常 */ - public function valid(object $object): void; + public function validObject(object $object): void; + + /** + * 检查参数是否合格 + * @param ReflectionParameter $reflectionParameter 要检查的参数反射 + * @param mixed $paramValue 参数的值 + * @return void + * @throws CheckErrorException 检查不通过时抛出异常 + */ + public function validParam(ReflectionParameter $reflectionParameter, mixed $paramValue): void; } # end of file diff --git a/src/main/Validor/Validator.php b/src/main/Validor/Validator.php index 6213d7e..d7e4c4b 100644 --- a/src/main/Validor/Validator.php +++ b/src/main/Validor/Validator.php @@ -9,10 +9,11 @@ use DreamCat\ObjectValid\Exception\CheckErrorException; use DreamCat\ObjectValid\Utils\AnnotationUtils; use DreamCat\ObjectValid\ValidationInterface; use ReflectionClass; +use ReflectionParameter; use ReflectionProperty; /** - * - + * 对象数值校验器,基于注解来做的 * @author vijay */ class Validator implements ValidationInterface @@ -20,34 +21,76 @@ class Validator implements ValidationInterface /** * @inheritDoc */ - public function valid(object $object): void + public function validObject(object $object): void { $ref = new ReflectionClass($object); $filter = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE; foreach ($ref->getProperties($filter) as $property) { - $allow = $property->isPublic(); - if (!$allow) { - $property->setAccessible(true); - } - if ($property->isInitialized($object)) { - $value = $property->getValue($object); - } else { - $value = null; + $this->checkProperty($object, $property); + } + } + + /** + * @inheritDoc + */ + public function validParam(ReflectionParameter $reflectionParameter, mixed $paramValue): void + { + $this->checkValue($paramValue, $reflectionParameter); + } + + /** + * 检查值是否符合注解要求 + * @param mixed $value + * @param ReflectionParameter|ReflectionProperty $reflection + * @return void + */ + protected function checkValue(mixed $value, ReflectionParameter|ReflectionProperty $reflection): void + { + foreach (AnnotationUtils::getAttrObjs($reflection, ValidAnnoInterface::class) as $attrObj) { + if ($attrObj->isValid($value)) { + continue; } - if (!$allow) { - $property->setAccessible(false); + $msg = $attrObj->errorMessage($reflection, $value); + if (strlen($msg)) { + throw new CheckErrorException($msg); } - foreach (AnnotationUtils::getAttrObjs($property, ValidAnnoInterface::class) as $attrObj) { - if (!$attrObj->isValid($value)) { - continue; - } - $msg = $attrObj->errorMessage($property, $value); - if (strlen($msg)) { - throw new CheckErrorException($msg); - } + } + $this->recursionCheck($value); + } + + protected function checkProperty(object $object, ReflectionProperty $reflection): void + { + $value = $this->getPropertyValue($object, $reflection); + $this->checkValue($value, $reflection); + } + + protected function getPropertyValue(object $object, ReflectionProperty $property): mixed + { + $allow = $property->isPublic(); + if (!$allow) { + $property->setAccessible(true); + } + if ($property->isInitialized($object)) { + $value = $property->getValue($object); + } else { + $value = null; + } + if (!$allow) { + $property->setAccessible(false); + } + return $value; + } + + protected function recursionCheck(mixed $value): void + { + if (is_array($value)) { + foreach ($value as $item) { + $this->recursionCheck($item); } + } elseif (is_object($value)) { + $this->validObject($value); } } } diff --git a/src/test/Cases/ValidatorTest.php b/src/test/Cases/ValidatorTest.php new file mode 100644 index 0000000..7b4cf37 --- /dev/null +++ b/src/test/Cases/ValidatorTest.php @@ -0,0 +1,68 @@ + 50, + "str" => "aabce", + "ary" => [ + 3, + 5, + 5, + 3, + ], + ]); + $validator = new Validator(); + $validator->validObject($pojo); + self::assertEquals($pojo, $pojo); + } + + /** + * - + * @return void + * @dataProvider errorData + */ + public function testError(object $obj, string $expectedError) + { + $this->expectException(CheckErrorException::class); + $this->expectErrorMessage($expectedError); + + $validator = new Validator(); + $validator->validObject($obj); + } + + public function errorData(): array + { + return [ + [ + DemoPojo::builder(["value" => 100]), + DemoPojo::class . "::value 不能大于 55 且不能小于 15", + ], + [ + DemoPojo::builder(["value" => 1]), + DemoPojo::class . "::value 不能大于 55 且不能小于 15", + ], + [ + DemoPojo::builder(["withMsgInt" => 100]), + "太大了", + ], + ]; + } +} + +# end of file diff --git a/src/test/Helper/DemoPojo.php b/src/test/Helper/DemoPojo.php new file mode 100644 index 0000000..08780e5 --- /dev/null +++ b/src/test/Helper/DemoPojo.php @@ -0,0 +1,32 @@ + $val) { + /** @noinspection PhpVariableVariableInspection */ + $obj->$key = $val; + } + return $obj; + } +} + +# end of file -- Gitee From e3d5e32110f3370ead9683ebd5648158d4a54afb Mon Sep 17 00:00:00 2001 From: vijay Date: Mon, 27 Sep 2021 15:10:35 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E6=B5=8B=E8=AF=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/Annotation/Size.php | 2 +- src/main/Exception/CheckErrorException.php | 50 ++++++++++++++++++++++ src/main/Validor/Validator.php | 2 +- src/test/Cases/ValidatorTest.php | 43 +++++++++++++++++++ src/test/Helper/DemoPojo.php | 10 ++++- 5 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/main/Annotation/Size.php b/src/main/Annotation/Size.php index 4208af1..9ccc4d8 100644 --- a/src/main/Annotation/Size.php +++ b/src/main/Annotation/Size.php @@ -40,7 +40,7 @@ class Size implements ValidAnnoInterface if ($this->sizeMin !== null) { $list[] = "不能小于 {$this->sizeMin}"; } - return "对象属性 {$reflection->class}::{$reflection->name} 的 size " . implode("且", $list); + return "对象属性 {$reflection->class}::{$reflection->name} 的 size " . implode(" 且", $list); } /** diff --git a/src/main/Exception/CheckErrorException.php b/src/main/Exception/CheckErrorException.php index 7b26435..2df518d 100644 --- a/src/main/Exception/CheckErrorException.php +++ b/src/main/Exception/CheckErrorException.php @@ -4,14 +4,64 @@ declare(strict_types=1); namespace DreamCat\ObjectValid\Exception; +use DreamCat\ObjectValid\Base\ValidAnnoInterface; +use JetBrains\PhpStorm\Immutable; +use JetBrains\PhpStorm\Pure; +use ReflectionParameter; +use ReflectionProperty; use RuntimeException; +use Throwable; /** * 检查的错误 * @author vijay */ +#[Immutable] class CheckErrorException extends RuntimeException { + /** + * @param ReflectionProperty|ReflectionParameter $reflection 对应的反射 + * @param mixed $value 传入的值 + * @param ValidAnnoInterface $invalid 未检查通过的注解 + * @param string $message + * @param int $code + * @param Throwable|null $previous + */ + #[Pure] + public function __construct( + private ReflectionProperty|ReflectionParameter $reflection, + private mixed $value, + private ValidAnnoInterface $invalid, + string $message, + int $code = 0, + Throwable $previous = null + ) { + parent::__construct($message, $code, $previous); + } + + /** + * @return ReflectionParameter|ReflectionProperty + */ + public function getReflection(): ReflectionParameter|ReflectionProperty + { + return $this->reflection; + } + + /** + * @return mixed + */ + public function getValue(): mixed + { + return $this->value; + } + + /** + * @return ValidAnnoInterface + */ + public function getInvalid(): ValidAnnoInterface + { + return $this->invalid; + } } # end of file diff --git a/src/main/Validor/Validator.php b/src/main/Validor/Validator.php index d7e4c4b..7c137b4 100644 --- a/src/main/Validor/Validator.php +++ b/src/main/Validor/Validator.php @@ -54,7 +54,7 @@ class Validator implements ValidationInterface } $msg = $attrObj->errorMessage($reflection, $value); if (strlen($msg)) { - throw new CheckErrorException($msg); + throw new CheckErrorException($reflection, $value, $attrObj, $msg); } } $this->recursionCheck($value); diff --git a/src/test/Cases/ValidatorTest.php b/src/test/Cases/ValidatorTest.php index 7b4cf37..a0470f4 100644 --- a/src/test/Cases/ValidatorTest.php +++ b/src/test/Cases/ValidatorTest.php @@ -61,6 +61,49 @@ class ValidatorTest extends TestCase DemoPojo::builder(["withMsgInt" => 100]), "太大了", ], + [ + DemoPojo::builder(["str" => "c"]), + DemoPojo::class . "::str 不匹配要求的正则表达式 #a#", + ], + [ + DemoPojo::builder(["withMsgStr" => "c"]), + "bbc", + ], + [ + DemoPojo::builder(["withMsgStr" => "a"]), + "aa", + ], + [ + DemoPojo::builder(["withMsgStr" => "aacerqwer"]), + "aa", + ], + [ + DemoPojo::builder( + [ + "ary" => [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + ], + ] + ), + DemoPojo::class . "::ary 的 size 不能大于 5 且不能小于 1", + ], + [ + DemoPojo::builder( + [ + "ary" => [ + DemoPojo::builder(["value" => 1]), + ], + ] + ), + DemoPojo::class . "::value 不能大于 55 且不能小于 15", + ], ]; } } diff --git a/src/test/Helper/DemoPojo.php b/src/test/Helper/DemoPojo.php index 08780e5..a9b7181 100644 --- a/src/test/Helper/DemoPojo.php +++ b/src/test/Helper/DemoPojo.php @@ -7,16 +7,20 @@ namespace DreamCat\ObjectValidTest\Helper; use DreamCat\ObjectValid\Annotation\NumberScope; use DreamCat\ObjectValid\Annotation\Pattern; use DreamCat\ObjectValid\Annotation\Size; +use JetBrains\PhpStorm\Immutable; /** * 示例类 * @author vijay */ +#[\Attribute] class DemoPojo { use SimpleBuilder; #[NumberScope(max: 55, min: 15)] + #[Immutable] + #[DemoPojo] private int $value; #[NumberScope(max: 38, message: "太大了")] @@ -25,7 +29,11 @@ class DemoPojo #[Pattern("#a#")] public string $str; - #[Size(sizeMax: 15)] + #[Pattern("#a#", "bbc")] + #[Size(sizeMin: 3, sizeMax: 6, message: "aa")] + public string $withMsgStr; + + #[Size(sizeMin: 1, sizeMax: 5)] public array $ary; } -- Gitee From a1343cda1a95d17604096bdd7a6c66b627df768f Mon Sep 17 00:00:00 2001 From: vijay Date: Mon, 27 Sep 2021 15:34:17 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E8=BE=BE=E5=88=B0100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/Utils/ReflectionUtils.php | 2 - src/main/Validor/Validator.php | 17 ++++++++ src/test/Cases/FnValidatorTest.php | 42 ++++++++++++++++++++ src/test/Cases/UtilsTest.php | 64 ++++++++++++++++++++++++++++++ src/test/Cases/ValidatorTest.php | 2 + src/test/Helper/DemoPojo.php | 8 +++- src/test/Helper/SimpleBuilder.php | 2 +- 7 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 src/test/Cases/FnValidatorTest.php create mode 100644 src/test/Cases/UtilsTest.php diff --git a/src/main/Utils/ReflectionUtils.php b/src/main/Utils/ReflectionUtils.php index 72b2127..95fe189 100644 --- a/src/main/Utils/ReflectionUtils.php +++ b/src/main/Utils/ReflectionUtils.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace DreamCat\ObjectValid\Utils; -use JetBrains\PhpStorm\Pure; use Reflector; /** @@ -18,7 +17,6 @@ class ReflectionUtils * @param Reflector $reflector 反射 * @return string 描述 */ - #[Pure] public static function getReflectDesc(Reflector $reflector): string { if (isset($reflector->name)) { diff --git a/src/main/Validor/Validator.php b/src/main/Validor/Validator.php index 7c137b4..a6dbd18 100644 --- a/src/main/Validor/Validator.php +++ b/src/main/Validor/Validator.php @@ -60,12 +60,24 @@ class Validator implements ValidationInterface $this->recursionCheck($value); } + /** + * 检查属性的值 + * @param object $object 对象 + * @param ReflectionProperty $reflection 要检查的属性反射 + * @return void + */ protected function checkProperty(object $object, ReflectionProperty $reflection): void { $value = $this->getPropertyValue($object, $reflection); $this->checkValue($value, $reflection); } + /** + * 获取属性的值 + * @param object $object 对象 + * @param ReflectionProperty $property 属性反射 + * @return mixed 属性值 + */ protected function getPropertyValue(object $object, ReflectionProperty $property): mixed { $allow = $property->isPublic(); @@ -83,6 +95,11 @@ class Validator implements ValidationInterface return $value; } + /** + * 递归检查 + * @param mixed $value 要检查的值 + * @return void + */ protected function recursionCheck(mixed $value): void { if (is_array($value)) { diff --git a/src/test/Cases/FnValidatorTest.php b/src/test/Cases/FnValidatorTest.php new file mode 100644 index 0000000..c1454ce --- /dev/null +++ b/src/test/Cases/FnValidatorTest.php @@ -0,0 +1,42 @@ + 50]), + 35, + ]; + try { + foreach ($ref->getParameters() as $idx => $parameter) { + $param = $params[$idx]; + $v->validParam($parameter, $param); + } + } catch (CheckErrorException $exception) { + self::assertEquals("v 不能大于 30", $exception->getMessage()); + self::assertEquals($params[1], $exception->getValue()); + self::assertEquals(NumberScope::class, get_class($exception->getInvalid())); + self::assertEquals($ref->getParameters()[1], $exception->getReflection()); + } + } +} + +# end of file diff --git a/src/test/Cases/UtilsTest.php b/src/test/Cases/UtilsTest.php new file mode 100644 index 0000000..2965961 --- /dev/null +++ b/src/test/Cases/UtilsTest.php @@ -0,0 +1,64 @@ +validObject($obj); } + #[Pure] public function errorData(): array { return [ diff --git a/src/test/Helper/DemoPojo.php b/src/test/Helper/DemoPojo.php index a9b7181..339131c 100644 --- a/src/test/Helper/DemoPojo.php +++ b/src/test/Helper/DemoPojo.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace DreamCat\ObjectValidTest\Helper; +use Attribute; use DreamCat\ObjectValid\Annotation\NumberScope; use DreamCat\ObjectValid\Annotation\Pattern; use DreamCat\ObjectValid\Annotation\Size; @@ -13,7 +14,7 @@ use JetBrains\PhpStorm\Immutable; * 示例类 * @author vijay */ -#[\Attribute] +#[Attribute] class DemoPojo { use SimpleBuilder; @@ -35,6 +36,11 @@ class DemoPojo #[Size(sizeMin: 1, sizeMax: 5)] public array $ary; + + public function testFn(DemoPojo $demoPojo, #[NumberScope(max: 30)] int $v) + { + + } } # end of file diff --git a/src/test/Helper/SimpleBuilder.php b/src/test/Helper/SimpleBuilder.php index 98a60e2..5fe0035 100644 --- a/src/test/Helper/SimpleBuilder.php +++ b/src/test/Helper/SimpleBuilder.php @@ -1,4 +1,4 @@ -