Architecture
PHP Validator is intentionally small. Its behavior is concentrated in a chainable validator, a mutable value container, and one exception type.
Repository map
| Path | Purpose |
|---|---|
src/EinLinuus/PhpValidator/Validator.php |
Public validation, transformation, array, and optional APIs. |
src/EinLinuus/PhpValidator/ValidatorValue.php |
Mutable value and optional-lock state used by Validator. |
src/EinLinuus/PhpValidator/ValidatorException.php |
Failure type with optional contextual data. |
examples/ |
Runnable examples for scalar values, arrays, shapes, optional fields, and transforms. |
docs/ |
Website-ready user and contributor documentation. |
composer.json |
Package identity and PSR-4 autoload configuration. |
Runtime model
Each Validator owns a ValidatorValue. Most public methods perform one of four operations:
- Check the current value and throw on failure.
- Replace the current value with a normalized or transformed result.
- Lock the value so later methods are skipped and a default is returned.
- Create child validators for array entries or schema fields.
raw input
|
v
ValidatorValue
|
+--> validation rule fails --> ValidatorException(message, data)
|
+--> transform updates current value
|
+--> optional lock returns a default
|
v
Validator::get()
The library returns the first failure. It does not collect multiple validation errors.
Chaining
Validation methods return the same Validator instance. This makes call order part of the contract:
$result = (new Validator($input)) ->isString('Expected a string') ->cleanString() ->transform(fn (string $value) => strtolower($value)) ->matches('/^[a-z]+$/', 'Only letters are allowed') ->get();
Later methods see the value produced by earlier transformations.
Array validation
isArray() creates a child validator for each input entry. After the callback runs, the child's value is copied back under the original key.
isArrayOfShape() creates a child validator for each schema key. Its output is a new array containing only schema keys, so it behaves as both validation and projection.
input array + callback/schema
|
v
child Validator
|
validate/transform
|
v
write child result into output array
Child exceptions are not wrapped. Their original message and context propagate to the caller.
Optional locking
optional() and optionalIf() lock the shared value container. Lock-aware methods return immediately, and get() returns the stored default rather than the original value.
isUnique() currently does not perform this lock check and is the only public rule with that exception.
Exceptions and context
Built-in failures call the private Validator::error() helper, which throws ValidatorException. The exception preserves:
- A message through inherited
Exception::getMessage(). - Arbitrary context through
ValidatorException::getData().
The library does not infer field paths. Array and shape callbacks should pass useful paths as context when callers need field-level error reporting.
Autoloading and namespaces
Composer maps:
EinLinuus\PhpValidator\ => src/
The source files also live under src/EinLinuus/PhpValidator/ and declare that same suffix. As a result, the current public namespace is:
EinLinuus\PhpValidator\EinLinuus\PhpValidator
Documentation and examples use this actual installed namespace.
Known behavioral constraints
cleanString()escapes HTML-sensitive characters; it does not remove HTML tags.- String
min()andmax()use byte length throughstrlen(), not multibyte character length. - Membership checks use non-strict
in_array()comparisons. isEqual()andisNotEqual()use strict comparison between integers and floats.- Date parsing follows
DateTimeconstructor behavior and transforms the value into a mutableDateTime. - Array shapes remove undeclared input keys.
- Validation stops at the first exception.
- No automated test suite or static-analysis configuration is currently included.
Treat these behaviors as compatibility constraints when changing the implementation.