Converters reference (Stage 1)¶
Converters are the first stage of the pipeline. They convert raw input (strings, mixed types from form submissions or JSON decoding) to a typed PHP value before any validators run.
A converter returns one of three sealed signals:
| Signal | Meaning |
|---|---|
valid($value) |
Conversion succeeded — typed value continues to Stage 3 (filters) |
null() |
Input is absent/empty — continues to Stage 2 (null policy) |
invalid($error) |
Bad format — pipeline stops immediately with an error |
Use use Verja\Verja as v or use Verja\Converter to access converters.
Integer¶
Converts numeric strings and integers to int. Accepts any value for which (int)$value
equals $value + 0 (i.e. the value represents a whole number). Absent/empty input (null
or '') signals null() and proceeds to the null policy stage.
Error key: NO_INTEGER.
Boolean¶
'boolean', 'bool', v::boolean(), new Converter\Boolean($stringTrue = [], $stringFalse = [], $overwrite = false)
Converts to PHP bool. Accepts:
- Native
bool— passes through int1/0— converted totrue/false- Strings (case-insensitive) 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.
->boolean('active')
// '1' → true, 'false' → false, 'maybe' → error NO_BOOLEAN
new Converter\Boolean(['on'], ['off'], true)
// 'on' → true, 'off' → false, 'yes' → error (defaults replaced)
Error key: NO_BOOLEAN.
Numeric¶
Converts numeric strings to int (if no decimal part) or float. Native int and
float values pass through unchanged.
Pass $decimalPoint to support alternative decimal separators:
Error key: NO_NUMERIC.
DateTime¶
'dateTime', v::dateTime(), new Converter\DateTime($timeZone = null, $format = null, $strict = false)
Converts a string to a PHP \DateTime object.
- Without
$format: parses any string accepted by PHP'sDateTimeconstructor. - With
$format: requires the value to match exactly (delegates toDateTime::createFromFormat()). $strict = true: additionally rejects overflow dates (e.g.2025-01-32).$timeZone: accepts a\DateTimeZoneinstance, a timezone name string, or a UTC offset integer.
Native \DateTime / \DateTimeImmutable values pass through unchanged.
->date('published_at')
// '2024-03-15' → DateTime, 'abc' → error NO_DATE
new Converter\DateTime('UTC', 'Y-m-d')
// '2024-03-15' → DateTime in UTC, '15.03.2024' → error NO_FORMATTED_DATE
Error keys: NO_DATE, NO_FORMATTED_DATE.
Json¶
Decodes a JSON string to a PHP value. Already-decoded values (arrays, integers, etc.)
pass through unchanged. 'null' JSON string and absent/empty input both signal null().
$type optionally asserts or further converts the decoded value:
$type |
Accepted decoded value | Delegates to |
|---|---|---|
null (default) |
any | — |
'array' |
indexed array | — |
'object' |
associative array | — |
'string' |
string | — |
'integer' |
integer | Converter\Integer |
'numeric' |
number | Converter\Numeric |
'bool' |
boolean | Converter\Boolean |
'datetime' |
date string | Converter\DateTime |
->any('payload', v::json(), new Gate()->int('a'))
// '{"a":1}' → ['a' => 1], validated as a gate with integer property 'a'
->any('tags', v::json('array'), v::min(1))
// '["php","oop"]' → ['php', 'oop'], '{"key":"val"}' → error NO_ARRAY
Error keys: INVALID_JSON, NO_ARRAY, NO_OBJECT, NO_STRING.
Custom converters¶
Implement Verja\ConverterInterface (or extend Verja\Converter), then register the
namespace so string definitions resolve automatically:
use Verja\ConvertResult;
use Verja\ConverterInterface;
class UlidConverter implements ConverterInterface
{
public function convert(mixed $value): ConvertResult
{
if ($value === null || $value === '') {
return ConvertResult::null();
}
if (!preg_match('/^[0-9A-Z]{26}$/', $value)) {
return ConvertResult::invalid(new Error('NO_ULID', $value, 'must be a valid ULID'));
}
return ConvertResult::valid($value);
}
}
Verja::addConverterNamespace('\\App\\Converter');
// now 'ulid' resolves to App\Converter\Ulid
See custom validators and filters for the full guide on extending the library.