首页 > 解决方案 > 尽管有限制,symfony 形式始终有效

问题描述

我无法让 Symfony 约束工作。
我在一个动作中有这个简单的形式:

   /**
     * @Route("reservation/{hash}/invoice", name="reservation-invoice")
     * @param Request $request
     * @param TranslatorInterface $translator
     * @param Reservation $reservation
     * @return JsonResponse|Response
     */
    public function invoiceAction(Request $request, TranslatorInterface $translator, Reservation $reservation)
    {
        if (empty($reservation->getInvoice())) {
            $invoice = new Invoice();
            $invoice->setReservation($reservation);
        } else {
            $invoice = $reservation->getInvoice();
        }

        $form = $this->createFormBuilder($invoice)
            ->add(
                'name',
                TextType::class,
                array(
                    'label' => $translator->trans('invoice.name'),
                    'required' => true,
                    'attr' => array(
                        'placeholder' => $translator->trans('invoice.name_placeholder'),
                        'class' => 'form-control',
                    ),
                    'constraints' => array(
                        new Length(array('min' => 3, 'max' => 50))
                    )
                )
            )
            ->add(
                'company',
                TextType::class,
                array(
                    'label' => $translator->trans('invoice.company'),
                    'required' => true,
                    'attr' => array(
                        'placeholder' => $translator->trans('invoice.company_placeholder'),
                        'class' => 'form-control',
                    ),
                    'constraints' => array(
                        new Length(array('min' => 3, 'max' => 50))
                    )
                )
            )
            ->add(
                'address',
                TextType::class,
                array(
                    'label' => $translator->trans('invoice.address1'),
                    'required' => true,
                    'attr' => array(
                        'placeholder' => $translator->trans('invoice.address1_placeholder'),
                        'class' => 'form-control',
                    ),
                    'constraints' => array(
                        new Length(array('min' => 3, 'max' => 100))
                    )
                )
            )
            ->add(
                'address2',
                TextType::class,
                array(
                    'label' => $translator->trans('invoice.address2'),
                    'required' => true,
                    'attr' => array(
                        'placeholder' => $translator->trans('invoice.address2_placeholder'),
                        'class' => 'form-control',
                    ),
                    'constraints' => array(
                        new Length(array('min' => 3, 'max' => 100))
                    )
                )
            )
            ->add(
                'nip',
                TextType::class,
                array(
                    'label' => $translator->trans('invoice.nip'),
                    'required' => true,
                    'attr' => array(
                        'placeholder' => $translator->trans('invoice.nip_placeholder'),
                        'class' => 'form-control',
                    ),
                    'constraints' => array(
                        new Length(array('min' => 3, 'max' => 10))
                    )
                )
            )
            ->setAction($this->generateUrl('reservation-invoice', array('hash' => $reservation->getHash())))
            ->setMethod('POST')
            ->getForm();

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $invoice = $form->getData();
            $this->db()->persist($invoice);
            $this->db()->flush();
            $this->addFlash('success', $translator->trans('invoice.data_changed'));
            return new JsonResponse(array(
                'redirect' => $this->generateUrl('reservation', array('hash' => $reservation->getHash()),
                    UrlGeneratorInterface::ABSOLUTE_URL)
            ));
        }

        return $this->response(
            array(
                'form' => $form->createView()
            )
        );
}

在配置中我有:

framework:
    validation:
        enabled: true

而且表格展示真的很简单:

{{ form_start(form) }}
    <div class="form-group">
        {{ form_label(form.name) }}
        {{ form_widget(form.name) }}
        {{ form_errors(form.name) }}
    </div>
    <div class="form-group">
        {{ form_label(form.company) }}
        {{ form_widget(form.company) }}
        {{ form_errors(form.company) }}
    </div>
    <div class="form-group">
        {{ form_label(form.address) }}
        {{ form_widget(form.address) }}
        {{ form_errors(form.address) }}
    </div>
    <div class="form-group">
        {{ form_label(form.address2) }}
        {{ form_widget(form.address2) }}
        {{ form_errors(form.address2) }}
    </div>
    <div class="form-group">
        {{ form_label(form.nip) }}
        {{ form_widget(form.nip) }}
        {{ form_errors(form.nip) }}
    </div>
{{ form_end(form) }}

当我提交带有空输入的表单时,$form->isValid()返回 true 并且我得到数据库错误,因为这些字段不能为空。
我怀疑我错过了一些东西,但根据Symfony 文档,这就是你所要做的。


编辑:
我设法在实体类注释中进行断言,例如:

/**
 * @var string
 * @ORM\Column(type="string", length=50)
 * @Assert\NotBlank()
 * @Assert\Length(min=3, max=50)
 */
private $name;

对我来说似乎很奇怪的是,保持控制器完好无损'required' => true根本不重要。当我发布空字段时,我收到 1 个错误,但是当我发布 1 个字母时,我收到 2 个错误:一个来自约束数组,一个来自注释。

标签: phpformssymfonysymfony4symfony-forms

解决方案


为了确保该字段不为空,我最后使用了 Assert\NotBlank:

/**
 * @var string
 * @ORM\Column(type="string", length=50)
 * @Assert\NotBlank()
 * @Assert\Length(min=3, max=50)
 */
private $name;

推荐阅读