在Symfony中成功验证后应用正确的逻辑
首先,我专门为这个问题创建了下面的整个示例,因为实际示例非常大,所以如果它看起来很愚蠢,那么现在就假设它不是 我正试图想出一个解决方案,这样,如果验证成功通过,我就可以在controller中调用正确的私有方法(在Symfony中成功验证后应用正确的逻辑,symfony,Symfony,首先,我专门为这个问题创建了下面的整个示例,因为实际示例非常大,所以如果它看起来很愚蠢,那么现在就假设它不是 我正试图想出一个解决方案,这样,如果验证成功通过,我就可以在controller中调用正确的私有方法(bankA()或bankB())。正如您在自定义验证约束中所看到的,我只检查$bank->code属性,但是条件实际上并不是那么简单(存在存储库检查等等)-(正如我前面所说,它是精简版本)。所以,请有人告诉我,在成功验证之后,我如何知道应该在控制器中调用哪个私有方法?如果有必要,我很乐意
bankA()
或bankB()
)。正如您在自定义验证约束中所看到的,我只检查$bank->code
属性,但是条件实际上并不是那么简单(存在存储库检查等等)-(正如我前面所说,它是精简版本)。所以,请有人告诉我,在成功验证之后,我如何知道应该在控制器中调用哪个私有方法?如果有必要,我很乐意创建专门的验证器,以便提供建议和示例
注意:我查阅了symfony group验证文档,但没有真正了解如何应用于我的场景
请求示例
{“id”:66,“code”:“A”}
{“id”:34,“code”:“B”}
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* @Route("bank", service="application_frontend.controller.bank")
*/
class BankController extends Controller
{
private $validator;
public function __construct(
ValidatorInterface $validator
) {
$this->validator = $validator;
}
/**
* @param Request $request
*
* @Route("")
* @Method({"POST"})
*
* @throws Exception
*/
public function indexAction(Request $request)
{
$content = $request->getContent();
$content = json_decode($content, true);
$bank = new Bank();
$bank->id = $content['id'];
$bank->code = $content['code'];
$errors = $this->validator->validate($bank);
if (count($errors)) {
throw new Exception($errors[0]->getMessage());
}
// OK, validation has passed so which one do I call now ?!?!
$this->bankA($bank);
$this->bankB($bank);
}
private function bankA(Bank $bank)
{
// Do something nice with Bank
}
private function bankB(Bank $bank)
{
// Do something bad with Bank
}
}
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class Bank extends Constraint
{
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
public function validatedBy()
{
return get_class($this).'Validator';
}
}
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class BankValidator extends ConstraintValidator
{
public function validate($bank, Constraint $constraint)
{
if ($bank->code == 'A') {
return;
}
if ($bank->code == 'B') {
return;
}
$this->context->buildViolation('Bank error')->addViolation();
}
}
银行模式
use Application\FrontendBundle\Validator\Constraint as BankAssert;
/**
* @BankAssert\Bank
*/
class Bank
{
/**
* @var int
*/
public $id;
/**
* @var string
*/
public $code;
}
自定义验证程序
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* @Route("bank", service="application_frontend.controller.bank")
*/
class BankController extends Controller
{
private $validator;
public function __construct(
ValidatorInterface $validator
) {
$this->validator = $validator;
}
/**
* @param Request $request
*
* @Route("")
* @Method({"POST"})
*
* @throws Exception
*/
public function indexAction(Request $request)
{
$content = $request->getContent();
$content = json_decode($content, true);
$bank = new Bank();
$bank->id = $content['id'];
$bank->code = $content['code'];
$errors = $this->validator->validate($bank);
if (count($errors)) {
throw new Exception($errors[0]->getMessage());
}
// OK, validation has passed so which one do I call now ?!?!
$this->bankA($bank);
$this->bankB($bank);
}
private function bankA(Bank $bank)
{
// Do something nice with Bank
}
private function bankB(Bank $bank)
{
// Do something bad with Bank
}
}
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class Bank extends Constraint
{
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
public function validatedBy()
{
return get_class($this).'Validator';
}
}
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class BankValidator extends ConstraintValidator
{
public function validate($bank, Constraint $constraint)
{
if ($bank->code == 'A') {
return;
}
if ($bank->code == 'B') {
return;
}
$this->context->buildViolation('Bank error')->addViolation();
}
}
取决于有多少代码,你可以这样做
if ('A' === $bank->getCode()) {
$this->bankA($bank);
} else {
$this->bankB($bank);
}
或者
尽管如此,建议将所有这些工作转移到专用服务中,而不是控制器中。然后在控制器中使用类似于
$this->container->get('do_something_to_bank.service')->processAction($bank);
背后的逻辑是什么?如果代码是A,你会叫bankA;如果代码是B,你会叫bankB?这是对的吗?但是A和B只是演示的目的,所以我不只是在验证中检查它是A还是B。对于存储库和一些其他服务,
$bank->code
还有更多的检查。$bank->code
可以是任何内容。我只是在方法名和请求负载中使用了A和B来简化代码,但显然我造成了误解,我只能怪我自己。总之,整个目标是知道在验证之后调用哪个方法。如果应用了X验证规则,则bankA()
,如果使用了Y验证,则将在控制器中调用bankB()
。另外,我实际上使用模型、工厂和服务来实现特定的逻辑,所以我并没有真正使用控制器来完成上面看到的所有代码。我只是想让它尽可能的整洁,足够公平。没有实际的代码,我发现很难对实际问题进行概念化。对不起,好吧,那就这么说吧。您想验证两次$bank
模型。针对BankStepOneValidator
执行一次,然后针对BankStepTwoValidator
。这可能吗?另一个选项:我是否可以向验证器传递某种变量/参数,以便上面的BankValidator
知道要运行哪个if语句?如果您只想执行步骤1,那么步骤2可以使用组和组序列。如果您只想验证它是否符合某些标准,那么我想您可以在第一个验证器中的对象中设置一个标志。老实说,我还是不知道你在找什么。