#php #validation #doctrine-orm #symfony
#php #проверка #доктрина-orm #symfony
Вопрос:
Как сказано в названии, мне действительно нужно создать процесс проверки с помощью Symfony. Я использую файл YAML, все в порядке. Но в некоторых случаях мне нужно проверить базу данных, прежде чем говорить, что данные проверены. Я искал в методе обратного вызова, но на самом деле он позволяет мне только проверять значения. Я искал, чтобы сделать внедрение зависимостей или даже передать определенную службу в качестве обратного вызова, но это тоже не помогает.
Короче говоря, вопрос таков: возможно ли этого добиться? Каким образом?
Комментарии:
1. Вам нужно пользовательское ограничение и валидатор, в который будет внедрена служба Doctrine. Вы пробовали это?
2. Никогда не пробовал, я нашел некоторую документацию по этому вопросу, но она кажется немного сложной для того, что мне нужно. Если это решение, я реализую это
3. Это не так уж и сложно. Взгляните сюда. symfony.com/doc/current/validation/custom_constraint.html Если у вас возникнут проблемы с реализацией этого, я буду рад помочь.
4. @dragoste: Я создал ответ, основанный на вашем предложении. Проблемы, которые у меня возникают с приоритетом тестов, не относятся к этому, так что большое спасибо за то, что дали мне подсказку, в которой я нуждался 🙂
Ответ №1:
С учетом того, что @dragoste сказал в комментариях, я искал, как сделать это с моим собственным ограничением.
Решение заключается в том, чтобы использовать пользовательское ограничение. Немного сложно понять, какой файл создавать и что делать, поэтому вот что я сделал.
Чтобы объяснить вам, что такое мои файлы, целью было проверить арендную плату, а не то, как она создается, а просто проверить, что в тот же момент нет арендной платы. Вот почему я должен использовать ограничение с Doctrine внутри него.
Создание папки валидатора внутри корня вашего пакета. Затем добавьте папку ограничений внутри папки Валидатора.
Создание файла RentDatesConstraint.php в папке Validaor/Constraints. Вот как это выглядит:
<?php
namespace ApiBundleValidatorConstraints;
use ApiBundleValidatorRentDatesValidator;
use SymfonyComponentValidatorConstraint;
class RentDatesConstraint extends Constraint
{
public $message = 'The beginning and ending date of the rent are not available for this vehicle.'; // note that you could use parameters inside it, by naming it with % to surround it
/**
* @inheritdoc
*/
public function validatedBy()
{
return RentDatesValidator::class; // this is the name of the class that will be triggered when you need to validate this constraint
}
/**
* @inheritdoc
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT; // says that this constraints is a class constraint
}
}
Теперь, когда вы создали свое собственное ограничение класса, вам нужно создать свой собственный валидатор.
Создайте файл RentDatesValidator.php в папке Валидатора.
<?php
namespace ApiBundleValidator;
use DoctrineBundleDoctrineBundleRegistry;
use DoctrineCommonCollectionsCollection;
use SymfonyComponentValidatorConstraint;
use SymfonyComponentValidatorConstraintValidator;
class RentDatesValidator extends ConstraintValidator
{
/**
* @var Registry $doctrine
*/
private $doctrine;
/**
* RentDatesValidator constructor.
* @param Registry $_doctrine
*/
public function __construct(Registry $_doctrine)
{
$this
->setDoctrine($_doctrine)
;
}
/**
* @param Registry $_doctrine
* @return $this
*/
public function setDoctrine(Registry $_doctrine)
{
$this->doctrine = $_doctrine;
return $this;
}
/**
* @inheritdoc
* @param Rent $_value
*/
public function validate($_value, Constraint $_constraint)
{
//do your stuff here
if ($testFails) {
$this
->context
->buildViolation($_constraint->message) // here you can pass an array to set the parameters of the string, surrounded by %
->addViolation()
;
}
}
}
Мы почти закончили, мы должны объявить его как сервис, поэтому здесь мы редактируем сервисы.yml в Resources / config
services:
# [...]
validator.rent_dates:
class: ApiBundleValidatorRentDatesValidator
tags:
- { name: validator.constraint_validator }
arguments: [ "@doctrine" ]
Здесь вы можете заметить, что я передал @doctrine service , но на самом деле вы можете передать любую службу, которую хотите, даже много, если вы правильно определяете класс RentDatesValidator, чтобы принимать эти службы в своем конструкторе.
И теперь все, что вам нужно сделать, это использовать это при проверке. Здесь мы редактируем Rent.yml в Resource/config/validation, чтобы добавить эту единственную строку:
ApiBundleEntityRent:
constraints:
- ApiBundleValidatorConstraintsRentDatesConstraint: ~
Мы закончили! Проверка будет работать при передаче вашего объекта в службу проверки.
Вы можете заметить, что это сделано с помощью YAML, лично я предпочитаю этот способ выполнения, поскольку он разделяет каждую часть (определение сущности, схему базы данных, файлы проверки, …), Но вы можете сделать это с помощью аннотаций, XML или даже чистого PHP. Это зависит от вас, поэтому, если вы хотите увидеть больше синтаксиса, вы все равно можете перейти по ссылке на документацию Symfony, чтобы узнать, как это сделать.