Skip to content

Validators reference

All validators are in the Verja\Validator\ namespace. In string definitions, use the class name with the first letter lowercase: 'strLen:3:20', 'emailAddress', 'notEmpty'.

Prefix ! to negate: '!notEmpty' passes only if the value is empty.

Short syntax with IDE autocompletion

Instead of new Verja\Validator\StrLen(3, 20) or string definitions, you can alias the base class and call validators as static methods:

use Verja\Validator as v;

$gate->accepts([
    'username' => [v::required(), v::strLen(3, 20)],
    'email'    => [v::required(), v::emailAddress()],
    'age'      => [v::nullable(), v::between(0, 150)],
]);

This works via __callStatic on the base class — no magic beyond PHP's own class aliasing. IDE autocompletion is driven by the @method annotations on Verja\Validator.

For custom validators, extend the base class in your own alias and add @method tags:

use Verja\Validator;

/**
 * @method static \App\Validator\DomainEmail domainEmail(string $domain)
 */
class v extends Validator {}

Your custom namespace must be registered first via Validator::registerNamespace('\\App\\Validator').


Prefix validators

Prefix validators run first, before filters and validators. On success they cast the value before passing it on — Nullable converts empty strings to null, Json decodes JSON to an array. If a prefix validator returns null after casting, the pipeline short-circuits silently (no further validators run).

Required and Nullable are mutually exclusive — adding one removes the other.

Required

'required', 'required:condition', v::required($condition = null), 
new Validator\Required($condition = null)

The value must be present and non-empty (not null or ''). Absent properties in a Gate are skipped unless this is set. Error key: IS_EMPTY.

An optional condition restricts when the field is required — see Required & nullable for the full syntax reference.

Nullable

'nullable', 'nullable:condition', v::nullable($condition = null), 
new Validator\Nullable($condition = null)

Allows the value to be null or absent. Casts empty strings ('') to null. If the value is null after casting, validation passes immediately and no further validators run. Error key: none (short-circuits silently).

An optional condition restricts when the field is nullable — see Required & nullable for the full syntax reference.

Json

'json', v::json(), new Validator\Json()

Value must be a valid JSON string. On success, casts the string to the decoded PHP value (associative array for objects, native types for scalars). Already-decoded values pass through unchanged. Combine with a nested Gate to validate the decoded structure:

->object('payload', new Validator\Json(), new Gate()->int('a'))
// '{"a":1}' → ['a' => 1], validated as a gate with integer property 'a'

Error keys: NO_STRING, INVALID_JSON.


String validators

NotEmpty

'notEmpty', v::notEmpty(), new Validator\NotEmpty()

Value must not be empty (null, '', [], 0, false all count as empty by PHP's empty()). Error key: IS_EMPTY (NOT_EMPTY when negated via !notEmpty).

StrLen

'strLen:3', 'strLen:3:20', v::strLen(int $min, int $max = 0, bool $utf8 = true),
new Validator\StrLen(int $min, int $max = 0, bool $utf8 = true)

String length must be between $min and $max characters (inclusive). $max = 0 means no upper limit. Uses PHP's mb_strlen() by default ($utf8 = true); pass $utf8 = false to fall back to byte-based strlen(). Error keys: STRLEN_TOO_SHORT, STRLEN_TOO_LONG.

Contains

'contains:foo', v::contains($subString),
new Validator\Contains($subString)

Value must contain $subString. Error key: NOT_CONTAINS.

StartsWith

'startsWith:https://', v::startsWith($prefix),
new Validator\StartsWith($prefix)

Value must start with $prefix. Error key: DOES_NOT_START_WITH.

EndsWith

'endsWith:.com', v::endsWith($suffix),
new Validator\EndsWith($suffix)

Value must end with $suffix. Error key: DOES_NOT_END_WITH.

Alpha

'alpha', 'alpha:true', v::alpha($allowSpaces = false),
new Validator\Alpha($allowSpaces = false)

Value must contain only alphabetical characters. Uses Unicode properties \pL (any Unicode letter, e.g. é or ω) and \pM (combining marks that attach to letters, e.g. the combining acute ´ in a decomposed é). Error key: CONTAINS_NON_ALPHA.

AlphaNumeric

'alphaNumeric', 'alphaNumeric:true', v::alphaNumeric($allowSpaces = false),
new Validator\AlphaNumeric($allowSpaces = false)

Value must contain only alphanumeric characters. Uses \pL\pM (letters and combining marks) and \pN (any Unicode number, e.g. ٣ or ). Error key: CONTAINS_NON_ALPHANUMERIC.

Slug

'slug', v::slug(), new Validator\Slug()

Value must contain only slug-safe characters: a-z, 0-9, -, _. Error key: NOT_SLUG.

PregMatch

'pregMatch:/^[a-z]+$/', v::pregMatch($pattern),
new Validator\PregMatch($pattern)

Value must match the regular expression $pattern (full PCRE pattern including delimiters). Error key: DOES_NOT_MATCH.


Numeric validators

Integer

v::integer(), new Validator\Integer()

Value must be an integer, a string that represents an integer, or a float whose value equals its rounded self (e.g. 1.0). Error key: NO_INTEGER.

Numeric

v::numeric($decimalPoint = '.'),
new Validator\Numeric($decimalPoint = '.')

Value must be numeric (integer or float, or a string representation). Uses PHP's is_numeric(). Error key: NOT_NUMERIC.

Boolean

v::boolean(),
new Validator\Boolean($stringTrue = [], $stringFalse = [], $overwrite = false)

Value must be boolean-like. Accepts PHP bool, any int, and the following strings by default:

  • truthy: '1', 'true', 't', 'yes', 'y'
  • falsy: '0', 'false', 'f', 'no', 'n'

Pass $stringTrue / $stringFalse to add extra accepted representations. Pass $overwrite = true to replace the defaults entirely. Error key: NOT_BOOLEAN.

Between

'between:0:100', v::between($min = null, $max = null),
new Validator\Between($min = null, $max = null)

Value must be between $min and $max (inclusive). Measures intelligently: - Numbers — numeric value - Strings — character length - Arrays — element count

Error keys: TOO_LOW, TOO_HIGH.

Min

'min:5', v::min($min),
new Validator\Min($min)

Value must be at least $min. Same smart measurement as Between. Error key: TOO_LOW.

Max

'max:100', v::max($max),
new Validator\Max($max)

Value must be at most $max. Same smart measurement as Between. Error key: TOO_HIGH.

Exactly

'exactly:2', v::exactly($count),
new Validator\Exactly($count)

Value must equal $count exactly. Measures intelligently: - Arrays — element count. Error key: WRONG_COUNT - Strings — character length. Error key: WRONG_LENGTH - Numbers — numeric value (supports float). Error key: WRONG_VALUE

$count accepts int or float (e.g. new Exactly(1.5)); string definitions like 'exactly:1.5' are coerced automatically.

'exactly:2'          // array must have 2 elements, string must be 2 chars, number must equal 2
'!exactly:0'         // useful for divisor checks: value must not be zero
new Exactly(1.5)     // number must be exactly 1.5

Format validators

EmailAddress

'emailAddress', v::emailAddress(), new Validator\EmailAddress()

Value must be a valid email address. Validated with a custom regex; does not implement full RFC 5322 — edge cases like quoted local parts ("foo bar"@example.com) are rejected. Error key: NO_EMAIL_ADDRESS.

Url

'url', v::url($coverage = 'complete', $schemes = ['https', 'http', 'ftp']),
new Validator\Url($coverage = 'complete', $schemes = ['https', 'http', 'ftp'])

Value must be a valid URL. Uses PHP's parse_url() internally.

$coverage controls how strictly the URL is checked: - 'valid'parse_url() must not return false - 'complete' (default) — scheme and host must be present; scheme must be in $schemes - 'active' — as complete, plus a DNS record must exist for the host - 'listening' — as active, plus the host must accept connections on the expected port

$schemes (default: ['https', 'http', 'ftp']) restricts allowed URL schemes.

Error keys: NO_URL, NOT_FULL_URL, SCHEME_NOT_ALLOWED, NO_DNS_RECORD, NO_PORT, NOT_LISTENING.

IpAddress

'ipAddress', 'ipAddress:v4', v::ipAddress($version = 'any', $range = 'any'),
new Validator\IpAddress($version = 'any', $range = 'any')

Value must be a valid IP address. Uses PHP's filter_var() with FILTER_VALIDATE_IP.

$version: 'v4' for IPv4 only, 'v6' for IPv6 only, 'any' (default) for either.

$range restricts the allowed address space: - 'any' (default) — no restriction - 'public' — must not be in a private range (FILTER_FLAG_NO_PRIV_RANGE) - 'public,unreserved' — public and not in a reserved range (FILTER_FLAG_NO_RES_RANGE) - 'private' — must be in a private range (public IPs are rejected)

Error keys: NO_IP_ADDRESS, NO_PUBLIC_IP_ADDRESS, IS_RESERVED_IP_ADDRESS, IS_PUBLIC_IP_ADDRESS.

CreditCard

'creditCard', v::creditCard(...$types),
new Validator\CreditCard($types = [])

Value must be a valid credit card number (Luhn algorithm). Spaces in the input are stripped before validation. Without $types, any Luhn-valid number passes. Pass one or more type names to additionally validate the card network:

v::creditCard('visa', 'mastercard')
// or as an array:
new Validator\CreditCard(['visa', 'mastercard'])

Supported types: visa, mastercard, amex, maestro, dinersclub.

Extend the class and overwrite protected static $cardTypes to register custom networks.

Error keys: NO_CREDIT_CARD (Luhn failure), WRONG_CREDIT_CARD (type mismatch).

Uuid

'uuid', v::uuid(), new Validator\Uuid()

Value must be a valid RFC 4122 UUID (versions 1–8). Error key: NO_UUID.


Date validators

DateTime

v::dateTime($format = null, $strict = false),
new Validator\DateTime($format = null, $strict = false)

Value must be a valid date/time. Without $format, validates via PHP's strtotime(); error key: NO_DATE. With $format, validates via date_create_from_format(); error key: NO_FORMATTED_DATE. $strict = true additionally reformats the parsed date and compares it back to the input, rejecting overflow dates like 2025-01-32.

Before

'before:2025-01-01', v::before($dateTime),
new Validator\Before($dateTime)

Value must be a date/time before $dateTime. Both the value and $dateTime can be a \DateTime instance or any string accepted by PHP's DateTime constructor (e.g. '2025-01-01', 'yesterday'). Using the DateTime filter beforehand is recommended for consistent parsing. Error keys: NOT_BEFORE, NO_DATE (value cannot be parsed).

After

'after:2020-01-01', v::after($dateTime),
new Validator\After($dateTime)

Value must be a date/time after $dateTime. Both the value and $dateTime can be a \DateTime instance or any string accepted by PHP's DateTime constructor. Using the DateTime filter beforehand is recommended for consistent parsing. Error keys: NOT_AFTER, NO_DATE (value cannot be parsed).


Type validators

IsString

'isString', v::isString(), new Validator\IsString()

Value must be a PHP string. Used internally by Gate::string(). Error key: NO_STRING.

IsArray

'isArray', v::isArray(), new Validator\IsArray()

Value must be a PHP array. Used internally by ArrayGate. Error key: NOT_AN_ARRAY.

IsStructured

'isStructured', v::isStructured(), new Validator\IsStructured()

Value must be an associative array or object. Used internally by Gate. Error key: NOT_STRUCTURED.

Truthful

'truthful', v::truthful(), new Validator\Truthful()

After converting to boolean, the value must be true. Accepts the same representations as the Boolean validator. Error key: NOT_TRUTHFUL.


Comparison validators

Equals

'equals:other_field', v::equals($opposite),
new Validator\Equals($opposite)

Value must equal the value at key $opposite in the validation context. Typically used for password confirmation fields.

->string('password',              'required', 'strLen:8')
->string('password_confirmation', 'required', 'equals:password')

Error key: NOT_EQUAL.

InArray

'inArray:["a","b","c"]', v::inArray($array),
new Validator\InArray($array)

Value must exist in $array. $array can be an array, a comma-separated string, or any Traversable. Parameters use JSON array notation in string definitions. Error key: NOT_IN_ARRAY.

Unique

v::unique($existing),
new Validator\Unique($existing)

Value must not already exist. $existing is either an array of taken values, or a callable that receives ($value, $context) and returns true if the value is already taken:

v::unique(['taken@example.com', 'other@example.com'])
v::unique(fn($v, $ctx) => DB::table('users')->where('email', $v)->where('id', '!=', $ctx['id'])->exists())

Error key: NOT_UNIQUE.


Other

Not

'!notEmpty', v::not($validator),
new Validator\Not($validator)

Negates any validator. $validator can be a string definition, instance, or callable. Error key: the inverse error of the wrapped validator.

Callback

new Validator\Callback($callback)

Delegates to a custom callable. The callable receives ($value, $context) and must return true on success or a Verja\Error on failure. Cannot be used as a string definition. See custom validators.