Валидация v1.0.0
Filter, Range, Regex, ArrayOf, PropertyValidator и ValidationException.
Правила валидации — PHP-атрибуты, реализующие Devcraft\Interfaces\ValidationRule. Возвращают null, если значение валидно, иначе короткое сообщение. Вход null всегда проходит (обязательность обрабатывает null fallback mapper).
Контракт ValidationRule
interface ValidationRule
{
/** Returns null when valid, otherwise a value-free error message. */
public function validate(mixed $value): ?string;
}Сообщения описывают только ожидание (must be numeric), не фактическое значение. Пути и actual types добавляют ReflectionMapper / ValidationException.
См. также: ValidationRule, PropertyValidator, ValidationException.
Атрибуты
Все validation-атрибуты нацелены на свойства и repeatable.
Filter
Обёртка над PHP filter_var:
use Devcraft\Attributes\Filter;
#[Filter(FILTER_VALIDATE_EMAIL)]
public string $email;
#[Filter(FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]])]
public int $quantity;Для FILTER_VALIDATE_BOOLEAN автоматически добавляется FILTER_NULL_ON_FAILURE, чтобы невалидные boolean отклонялись, а не coercились в false.
Сообщение при ошибке: must pass filter {id}.
См. Filter.
Range
Числовые границы для int или float:
use Devcraft\Attributes\Range;
#[Range(min: 1, max: 65535)]
public int $port;
#[Range(min: 0.0)]
public float $ratio;Любую границу можно опустить. Нечисловые значения → must be numeric.
См. Range.
Regex
Совпадение строки с паттерном:
use Devcraft\Attributes\Regex;
#[Regex('/^[0-9a-f-]{36}$/i')]
public string $id;Конструктор проверяет паттерн через preg_match и бросает InvalidArgumentException, если выражение невалидно. Не-string → must be a string.
См. Regex.
ArrayOf
Гарантирует, что значение — list, элементы которого соответствуют имени типа:
use Devcraft\Attributes\ArrayOf;
#[ArrayOf('string')]
public array $tags;
#[ArrayOf(Address::class)]
public array $locations;Встроенные: mixed, string, int/integer, float/double, bool/boolean, array, object. Остальные имена — проверка class/interface через instanceof.
В ReflectionMapper ArrayOf также управляет вложенной конверсией до валидации.
См. ArrayOf.
PropertyValidator
Devcraft\Validation\PropertyValidator запускает правила атрибутов без гидратации:
use Devcraft\Validation\PropertyValidator;
use ReflectionProperty;
$validator = new PropertyValidator();
$errors = $validator->validateValue(
new ReflectionProperty(Profile::class, 'port'),
0,
);
// ['must be greater than or equal to 1']
$objectErrors = $validator->validateObject($profile);
// ['port' => [...], ...]validateObject() смотрит только public, non-static, initialized свойства. Атрибуты не из ValidationRule игнорируются. Несколько правил на одном свойстве дают несколько сообщений.
ValidationException
Бросается ReflectionMapper, когда один или несколько обязательных путей свойств не проходят:
use Devcraft\Exceptions\ValidationException;
try {
Profile::fromArray($payload);
} catch (ValidationException $exception) {
$exception->getMessage();
// "Validation failed for: port, address.city"
$exception->getErrors();
// [
// 'port' => ['must be greater than or equal to 1'],
// 'address.city' => ['must be string'],
// ]
}getErrors() возвращает array<string, list<string>> с ключами — dotted property paths.