Validator allows to check data in any format. Here are some of the most common use cases.
In the simplest case, the validator can be used to check a single value:
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Regex;
use Yiisoft\Validator\Validator;
$value = 'mrX';
$rules = [
new Length(min: 4, max: 20),
new Regex('~^[a-z_\-]*$~i'),
];
$result = (new Validator())->validate($value, $rules);
Note: Use Each rule to validate multiple values of the same type.
It's possible to validate an array both as a whole and by individual items. For example:
use Yiisoft\Validator\Rule\FilledAtLeast;
use Yiisoft\Validator\Rule\Count;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Rule\Required;
use Yiisoft\Validator\Validator;
$data = [
'name' => 'John',
'age' => 17,
'email' => 'john@example.com',
'phone' => null,
];
$rules = [
// The rules that are not related to a specific property
// At least one of the properties ("email" and "phone") must be passed and have non-empty value.
new FilledAtLeast(['email', 'phone']),
// The rules related to a specific property.
'name' => [
// The name is required (must be passed and have non-empty value).
new Required(),
// The name's length must be no less than 2 characters.
new Length(min: 2),
],
'age' => new Number(min: 21), // The age must be at least 21 years.
'email' => new Email(), // Email must be a valid email address.
];
$result = (new Validator())->validate($data, $rules);
Note: Use Nested rule to validate nested arrays and Each rule to validate multiple arrays.
Similar to arrays, it's possible to validate an object both as a whole and by individual properties.
For objects there is an additional option to configure validation with PHP attributes which allows to not pass the rules separately in explicit way (passing just the object itself is enough). For example:
use Yiisoft\Validator\Rule\FilledAtLeast;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Rule\Required;
use Yiisoft\Validator\Validator;
#[FilledAtLeast(['email', 'phone'])]
final class Person
{
public function __construct(
#[Required]
#[Length(min: 2)]
public readonly ?string $name = null,
#[Number(min: 21)]
public readonly ?int $age = null,
#[Email]
public readonly ?string $email = null,
public readonly ?string $phone = null,
) {
}
}
$person = new Person(name: 'John', age: 17, email: 'john@example.com', phone: null);
$result = (new Validator())->validate($person);
Note: readonly properties are supported only starting from PHP 8.1.
Note: Use Nested rule to validate related objects and Each rule to validate multiple objects.
Most of the time creating a custom data set is not needed because of built-in data sets and automatic normalization of all types during validation. However, this can be useful, for example, to change a default value for certain properties:
use Yiisoft\Validator\DataSetInterface;
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Validator;
final class MyArrayDataSet implements DataSetInterface
{
public function __construct(private array $data = [],)
{
}
public function getPropertyValue(string $property): mixed
{
if ($this->hasProperty($property)) {
return $this->data[$property];
}
return $property === 'name' ? '' : null;
}
public function getData(): array
{
return $this->data;
}
public function hasProperty(string $property): bool
{
return array_key_exists($property, $this->data);
}
}
$data = new MyArrayDataSet([]);
$rules = ['name' => new Length(min: 2), 'age' => new Number(min: 21)];
$result = (new Validator())->validate($data, $rules);
For a single rule, there is an option to omit the array:
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Validator;
$value = 7;
$rule = new Number(min: 42);
$result = (new Validator())->validate($value, $rule);
Could help reuse the same set of rules across different places. Two ways are possible - using PHP attributes and specifying explicitly via interface method implementation.
In this case, the rules will be automatically parsed, no need to additionally do anything.
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Validator;
final class PersonRulesProvider
{
#[Length(min: 2)]
public string $name;
#[Number(min: 21)]
protected int $age;
}
$data = ['name' => 'John', 'age' => 18];
$rulesProvider = new PersonRulesProvider();
$result = (new Validator())->validate($data, $rulesProvider);
Providing rules via interface method implementation has priority over PHP attributes. So, in case both are present, the attributes will be ignored without causing an exception.
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\RulesProviderInterface;
use Yiisoft\Validator\Validator;
final class PersonRulesProvider implements RulesProviderInterface
{
#[Length(min: 2)] // Will be silently ignored.
public string $name;
#[Number(min: 21)] // Will be silently ignored.
protected int $age;
public function getRules() : iterable
{
return ['name' => new Length(min: 2), 'age' => new Number(min: 21)];
}
}
$data = ['name' => 'John', 'age' => 18];
$rulesProvider = new PersonRulesProvider();
$result = (new Validator())->validate($data, $rulesProvider);
In this way, rules are provided in addition to data in the same object. Only interface method implementation is
supported. Note that the rules
argument is null
in the validate()
method call.
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\RulesProviderInterface;
use Yiisoft\Validator\Validator;
final class Person implements RulesProviderInterface
{
#[Length(min: 2)] // Not supported for using with data objects. Will be silently ignored.
public string $name;
#[Number(min: 21)] // Not supported for using with data objects. Will be silently ignored.
protected int $age;
public function getRules(): iterable
{
return ['name' => new Length(min: 2), 'age' => new Number(min: 21)];
}
}
$data = new Person(name: 'John', age: 18);
$result = (new Validator())->validate($data);