Валидаторы в Битрикс
Валидация это процесс проверки данных на соответствие определенным правилам/условиями и этот процесс является распространенней задачей в веб-приложениях, например валидация данных отправленных форм, валидация перед записью в базу данных или передачей в сервисы.
В Битрикс существует единый сервис валидации \Bitrix\Main\Validation\ValidationService, обратиться к которому можно через Локатор служб по ключу main.validation.service, на вход валидатора передается любой объект, размеченный в соответствии с правилами:
$validation = Bitrix\Main\DI\ServiceLocator::getInstance()->get('main.validation.service');
$result = $validation->validate(object);
Валидация это не магия, Битрикс не знает как нужно валидировать именно ваш объект, для корректной работы механизма, необходимо чтобы свойства вашего объекта был размечены правилами валидации.
Модификаторы доступа у свойств не учитываются, валидация происходит через рефлексию, если атрибут не установлен, он будет пропущен при валидации:
<?php
use Bitrix\Main\Validation\Rule\NotEmpty;
use Bitrix\Main\Validation\Rule\PositiveNumber;
class Accrual
{
public function __construct(
/**
* Проверка на число
* @var int
*/
#[PositiveNumber]
public int $userId,
/**
* Проверка на число
* @var int
*/
#[PositiveNumber]
public int $coinCount,
/**
* Примечение к начислению
* @var string
*/
#[NotEmpty]
public string $desc
)
{
}
}
$accrual = new Accrual(
userId: -1,
coinCount: 100,
desc: ""
);
$validation = Bitrix\Main\DI\ServiceLocator::getInstance()->get('main.validation.service');
$validationResult = $validation->validate($accrual);
if (!$validationResult->isSuccess()) {
foreach ($validationResult->getErrors() as $error) {
echo 'Аргумент: ' . $error->getCode() . ' - ' . $error->getMessage() . '<br>';
}
return;
}
Есть готовый набор валидаторов, можно сделать свои валидаторы на примере уже существующих, но с адаптацией под свою логику:
ElementsTypeEmailInArrayLengthMaxMinNotEmptyPhonePhoneOrEmailPositiveNumberRangeRegExpUrlJson
Валидация объектов
<?php
use Bitrix\Main\Validation\Rule\Recursive\Validatable;
use Bitrix\Main\Validation\Rule\NotEmpty;
use Bitrix\Main\Validation\Rule\PositiveNumber;
class Buyer
{
public function __construct(
#[PositiveNumber]
public ?int $id,
#[Validatable]
public ?Order $order
)
{
}
}
class Order
{
public function __construct(
#[PositiveNumber]
public int $id,
#[Validatable]
public ?Payment $payment
)
{
}
}
class Payment
{
public function __construct(
#[NotEmpty]
public string $status,
// добавили свой вариант ответа
#[NotEmpty(errorMessage: 'Custom message error')]
public string $systemCode
)
{
}
}
$buyer = new Buyer(
id: 123,
order: new Order(
// допустили ошибку
id: 0,
payment: new Payment(
// допустили ошибку
status: '',
// допустили ошибку
systemCode: ''
)
)
);
$validation = Bitrix\Main\DI\ServiceLocator::getInstance()->get('main.validation.service');
$validationResult = $validation->validate($buyer);
if (!$validationResult->isSuccess()) {
foreach ($validationResult->getErrors() as $error) {
echo 'Аргумент: ' . $error->getCode() . ' - ' . $error->getMessage() . '<br>';
}
}