lsr / object-validation
Laser framework core - Object validation
Requires
- php: >= 8.4
- lsr/serializer: ^0.3
- nette/utils: ^4.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- jetbrains/phpstorm-attributes: ^1.2
- phpstan/extension-installer: ^1.2
- phpstan/phpstan: ^2.0
- phpstan/phpstan-dibi: ^2.0
- phpstan/phpstan-nette: ^2.0
- phpunit/phpunit: ^12
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
lsr/object-validation validates public object properties using PHP attributes. It supports fail-fast validation, collecting multiple validation errors and recursive validation of nested objects.
Requirements
- PHP
>= 8.4. lsr/serializer^0.3and Nette Utils^4.0(installed by Composer).- No PHP extensions are declared directly in this package's manifest.
StringLengthusesmb_strlen()with UTF-8, so that validator needsext-mbstringor a compatible polyfill.
Installation
composer require lsr/object-validation
Validating an object
require_once __DIR__ . '/vendor/autoload.php'; use Lsr\ObjectValidation\Attributes\IntRange; use Lsr\ObjectValidation\Attributes\Required; use Lsr\ObjectValidation\Attributes\StringLength; use Lsr\ObjectValidation\Exceptions\ValidationMultiException; use Lsr\ObjectValidation\Validator; final class BookingInput { #[Required] #[StringLength(min: 1, max: 80)] public ?string $name = null; #[IntRange(min: 1, max: 20)] public int $players = 1; } $input = new BookingInput(); $input->name = 'Ada'; $validator = new Validator(); $validator->validate($input); // Returns normally when valid. $input->players = 0; try { $validator->validateAll($input); } catch (ValidationMultiException $exception) { foreach ($exception->exceptions as $error) { // Handle each ValidationException in the application's error response. $message = $error->getMessage(); } }
Validation behavior
Validator inspects public properties only. It does not deserialize input or coerce values into property types.
validate()throwsLsr\ObjectValidation\Exceptions\ValidationExceptionat the first validation failure.validateAll()collects failures intoValidationMultiException, whose publicexceptionsarray contains the failures. Nested objects can produce nested multi-exceptions.Requiredrejects null or uninitialized properties, not empty strings. Combine it withStringLength(min: 1)when an empty string is invalid.- Other validator attributes are skipped for uninitialized properties and nullable null values. Add
Requiredwhen the field must be supplied. - Nested object-valued properties are validated recursively, with dotted property paths and cycle protection. Arrays of objects are not traversed automatically.
validateAll()skips recursion through virtual or hooked properties. #[Lsr\ObjectValidation\Attributes\NoValidate]skips a property or an entire class.
See src/Attributes for DateString, Email, IntRange, Numeric, Regex, Required, StringLength, Uri and Url. Custom PHP property attributes can implement Lsr\ObjectValidation\Attributes\Validator::validateValue() and throw ValidationException to participate in the same flow.
Development
CI runs on PHP 8.4 and 8.5. Install development dependencies and run the same three checks locally:
composer install --prefer-dist --no-interaction --no-progress composer cs vendor/bin/phpstan analyse --no-progress vendor/bin/phpunit --no-coverage
composer cs checks PHP coding style without changing files; composer cs:fix applies fixes (composer cbf is an alias). The test script enables Xdebug coverage mode; coverage reports need a compatible coverage driver. Configuration is in phpunit.xml, phpstan.neon and .php-cs-fixer.php.
The validation suite uses local object fixtures and needs no external services. CI installs mbstring for string-length validation and disables coverage, so it does not require a coverage driver.
AI coding assistance
See LSR Skills for AI agent skills for working with the LSR framework.
License
Licensed under the MIT License.