feat(validation): add type and size-based validation methods

Add string, array, min, max, between, and size validators to the
Validator class. A private measure helper centralizes size semantics
for numbers (value), strings (length), and arrays (element count).
This commit is contained in:
kj
2026-09-03 14:35:02 -03:00
parent 15df7c8d96
commit 1f366830bc

View File

@@ -228,6 +228,117 @@ class Validator
return filter_var($subject, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null;
}
/**
* Checks if the value is a string.
*
* Note this is the strict type check: a PHP integer (e.g. 42) or an array
* fails, while any string - including a numeric string like "42" - passes.
*
* @param mixed $subject The value to check.
*
* @return bool
*/
public static function string(mixed $subject): bool
{
return is_string($subject);
}
/**
* Checks if the value is an array.
*
* @param mixed $subject The value to check.
*
* @return bool
*/
public static function array(mixed $subject): bool
{
return is_array($subject);
}
/**
* Measures a value for the size-based rules (min/max/between/size).
*
* A numeric value is measured by its number, a plain string by its
* character length, and an array by its element count. This single helper
* keeps the size semantics consistent and is where the file case (kilobytes)
* is added later.
*
* @param mixed $subject The value to measure.
*
* @return float
*/
private static function measure(mixed $subject): float
{
if (is_numeric($subject)) {
return (float) $subject;
}
if (is_string($subject)) {
return (float) (function_exists('mb_strlen') ? mb_strlen($subject) : strlen($subject));
}
if (is_array($subject)) {
return (float) count($subject);
}
return 0.0;
}
/**
* Checks if the measured value is greater than or equal to a minimum.
*
* @param mixed $subject The value to check.
* @param mixed $min The minimum length, number or count.
*
* @return bool
*/
public static function min(mixed $subject, mixed $min): bool
{
return static::measure($subject) >= (float) $min;
}
/**
* Checks if the measured value is less than or equal to a maximum.
*
* @param mixed $subject The value to check.
* @param mixed $max The maximum length, number or count.
*
* @return bool
*/
public static function max(mixed $subject, mixed $max): bool
{
return static::measure($subject) <= (float) $max;
}
/**
* Checks if the measured value is within an inclusive range.
*
* @param mixed $subject The value to check.
* @param mixed $min The lower bound.
* @param mixed $max The upper bound.
*
* @return bool
*/
public static function between(mixed $subject, mixed $min, mixed $max): bool
{
$size = static::measure($subject);
return $size >= (float) $min && $size <= (float) $max;
}
/**
* Checks if the measured value is exactly a given size.
*
* @param mixed $subject The value to check.
* @param mixed $size The expected length, number or count.
*
* @return bool
*/
public static function size(mixed $subject, mixed $size): bool
{
return static::measure($subject) === (float) $size;
}
/**
* Checks if the value is a valid email address.
*