leightonthomas / validation
Type safe composable validation library that integrates with static analysis.
0.3.0
2021-02-09 19:11 UTC
Requires
- php: ^7.4 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^9.4
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.4
- weirdan/codeception-psalm-module: ^0.13
Suggests
- leightonthomas/validation-bundle: Symfony bundle for this library.
- leightonthomas/validation-psalm-plugin: Improved Psalm support for certain validation rules.
This package is auto-updated.
Last update: 2024-04-10 05:28:41 UTC
README
This library provides composable type-safe validation that works great with Psalm.
A stable version has not yet been reached so things are still subject to change.
Installation
- Install the validator package itself
composer require leightonthomas/validation
- Install the Psalm plugin
composer require --dev leightonthomas/validation-psalm-plugin
- Enable the Psalm plugin
psalm-plugin enable leightonthomas/validation-psalm-plugin
Without the plugin, you won't receive for full typing for certain rules (e.g. dynamically created object-like arrays), and they may default to less-specific types.
Documentation
See the docs folder.
Usage
- Create a
LeightonThomas\Validation\ValidatorFactory
instance - Register all checkers with the factory
- Compose rules
- Create a validator for your rules with the validator factory
Example
This example assumes the Psalm plugin is installed and enabled.
<?php use LeightonThomas\Validation\Checker\Combination\ComposeChecker; use LeightonThomas\Validation\Checker\Combination\UnionChecker; use LeightonThomas\Validation\Checker\Scalar\Numeric\IsGreaterThanChecker; use LeightonThomas\Validation\Checker\Scalar\IsScalarChecker; use LeightonThomas\Validation\Checker\StrictEqualsChecker; use LeightonThomas\Validation\Rule\Arrays\IsDefinedArray; use LeightonThomas\Validation\Rule\Combination\Compose; use LeightonThomas\Validation\Rule\Combination\Union; use LeightonThomas\Validation\Rule\Object\IsInstanceOf; use LeightonThomas\Validation\Rule\Scalar\Numeric\IsGreaterThan; use LeightonThomas\Validation\Rule\Scalar\Integer\IsInteger; use LeightonThomas\Validation\Rule\StrictEquals; use LeightonThomas\Validation\ValidatorFactory; use LeightonThomas\Validation\Checker\Arrays\IsDefinedArrayChecker; // Set up the ValidatorFactory and register checkers $factory = new ValidatorFactory(); $factory->register(new IsDefinedArrayChecker($factory)); $factory->register(new IsScalarChecker()); $factory->register(new StrictEqualsChecker()); $factory->register(new ComposeChecker($factory)); $factory->register(new IsGreaterThanChecker()); $factory->register(new UnionChecker($factory)); // Compose rules $isCurrencyCode = Union::of(new StrictEquals('GBP')) ->or(new StrictEquals('USD')) ->setMessage(Union::ERR_MESSAGE, 'This must be a valid currency code.') ; $isMoneyAmount = Compose::from(new IsInteger()) ->and(new IsGreaterThan(0)) ; $myRule = IsDefinedArray::of('currency', $isCurrencyCode) ->and('amount', $isMoneyAmount) ->andMaybe('time', new IsInstanceOf(DateTimeInterface::class)) ; // Create a reusable validator for the Rule to validate against $validator = $factory->create($myRule); $result = $validator->validate([]); if ($result->isValid()) { // This will be typed as array{amount: int, currency: string(GBP)|string(USD), time?: DateTimeInterface} $outputValue = $result->getValue(); } else { /** * Output: * [ * 'currency' => [ * 'This must be a valid currency code.', * ], * 'amount' => [ * 'This value must be of type integer.', * ], * ] */ var_dump($result->getErrors()); }