jardissupport / validation
Object graph validation with recursive traversal, 21 built-in validators, and fluent field rule composition
Requires
- php: >=8.2
- jardissupport/contract: ^1.0
Requires (Dev)
- phpstan/phpstan: ^2.0.4
- phpunit/phpunit: ^10.5
- squizlabs/php_codesniffer: ^3.11.2
This package is auto-updated.
Last update: 2026-03-31 07:37:49 UTC
README
Part of the Jardis Business Platform — Enterprise-grade PHP components for Domain-Driven Design
Object graph validation with recursive traversal. Walks entire object hierarchies — including nested aggregates and collections — applying field-level rules with 21 built-in validators. Fluent composition, circular reference detection, and break-on-first-error mode.
Features
- Recursive Object Traversal — validates nested objects and collections automatically, no manual wiring
- 21 Built-in Validators — NotBlank, Email, Url, Uuid, Range, Length, Format, DateTime, Ip, Iban, CreditCard, PhoneNumber, Json, Alphanumeric, Contain, Count, Positive, Equals, UniqueItems, NotEmpty, Callback
- Fluent Field Rules —
CompositeFieldValidatorcomposes per-field validators with a chainablefield()API - Break Mode — stop at first error for guard-style validation before deeper checks
- ValidatorRegistry — maps classes (and parent types) to their validators with exact and inheritance-based matching
- Circular Reference Detection — tracks visited objects to prevent infinite loops in cyclic graphs
- Exclude Fields — skip fields conditionally, supporting partial-update patterns
- Depth Limiting —
ValidationContexttracks traversal levels to cap recursion depth
Installation
composer require jardissupport/validation
Quick Start
use JardisSupport\Validation\CompositeFieldValidator; use JardisSupport\Validation\ValidatorRegistry; use JardisSupport\Validation\ObjectValidator; use JardisSupport\Validation\Validator\NotBlank; use JardisSupport\Validation\Validator\Email; use JardisSupport\Validation\Validator\Length; // Define rules for a single class $userValidator = new CompositeFieldValidator(); $userValidator->field('name')->validates(NotBlank::class)->validates(Length::class, ['min' => 2, 'max' => 100]); $userValidator->field('email')->validates(NotBlank::class)->validates(Email::class); // Register and validate $registry = new ValidatorRegistry(); $registry->register(User::class, $userValidator); $validator = new ObjectValidator($registry); $result = $validator->validate($user); if (!$result->isValid()) { print_r($result->getErrors()); }
Advanced Usage
use JardisSupport\Validation\CompositeFieldValidator; use JardisSupport\Validation\ValidatorRegistry; use JardisSupport\Validation\ObjectValidator; use JardisSupport\Validation\Validator\NotBlank; use JardisSupport\Validation\Validator\Uuid; use JardisSupport\Validation\Validator\Email; use JardisSupport\Validation\Validator\Range; // Break-mode: abort all validation if the id field is blank $orderValidator = new CompositeFieldValidator(); $orderValidator->field('id')->breaksOn(Uuid::class); $orderValidator->field('email')->validates(Email::class); $orderValidator->field('amount')->validates(Range::class, ['min' => 0.01]); // Partial updates: skip these fields unless id is present $orderValidator->excludeFields(['createdAt', 'updatedAt']); // ValidatorRegistry resolves by exact class or parent/interface match $registry = new ValidatorRegistry(); $registry->register(Order::class, $orderValidator); $registry->register(OrderLine::class, $lineValidator); // ObjectValidator walks the entire graph — Order + nested OrderLine collection $validator = new ObjectValidator($registry); $result = $validator->validate($order); // Errors keyed by short class name: ['order' => [...], 'orderLine' => [...]]
Documentation
Full documentation, guides, and API reference:
docs.jardis.io/support/validation
License
This package is licensed under the PolyForm Shield License 1.0.0. Free for all use except building competing frameworks or developer tooling.