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)]
public int $age;
}
$data = ['name' => 'John', 'age' => 18];
$rulesProvider = new PersonRulesProvider();
$result = (new Validator())->validate($data, $rulesProvider);When an object implementing RulesProviderInterface is passed as the $rules argument (second argument of
validate()), only the rules from getRules() are used. PHP attributes on the object are not parsed in this case.
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)] // Ignored because the object is passed as the $rules argument.
public string $name;
#[Number(min: 21)] // Ignored because the object is passed as the $rules argument.
public 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. Both PHP attributes and getRules() method
are supported — their rules are merged (attribute rules are applied first). 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
{
public function __construct(
#[Length(min: 2)] // Merged with rules from getRules(). Attribute rules are applied first.
public string $name = '',
#[Number(min: 21)] // Merged with rules from getRules(). Attribute rules are applied first.
public int $age = 0,
) {
}
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);