Symfony3 @Assert \有效不起作用

时间:2016-01-20 08:58:46

标签: php validation symfony

我安装了Symfony3,我正在尝试使用@Assert \ Valid注释验证普通表单中的formchild(实体子/非映射字段)。我做不到,所以我尝试了手册中的例子: http://symfony.com/doc/current/reference/constraints/Valid.html

这个例子,在Symfony 3中,不起作用(至少对我而言)。 这是使用@Assert \ Valid的地方。在这种情况下,Symfony如何知道(例如来自手册)来验证地址实体而不是任何其他实体?

 /**
 * @Assert\Valid
 */
protected $address;

是否有人试图测试手册中的示例,看看它是否有效?

有人可以提供手册中的工作示例吗?我不知道我做错了什么..

这是我的TestingController.php:

namespace WebsiteBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use WebsiteBundle\Entity\Author;
use WebsiteBundle\Form\Type\AuthorRegistrationType;

class TestingController extends Controller
{

    public function registerAccountAction(Request $request)
    {

        $author = new Author();

        $form = $this->createForm(AuthorRegistrationType::class, $author, array(
            'required' => false
        ));

        $form->handleRequest($request);

        if($form->isSubmitted() && $form->isValid()) {

           echo "It works";
        }


        return $this->render('TemplatesBundle:Default:testing_registration.html.twig', array(
            'form' => $form->createView(),
        ));
    }
}

AuthorRegistrationType.php:

namespace WebsiteBundle\Form\Type;


use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class AuthorRegistrationType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add("firstname")
            ->add("lastname")
            ->add("zipcode", TextType::class, array('mapped' => false))
            ->add("street",  TextType::class, array('mapped' => false))
            ->add('save', SubmitType::class);
    }

}

作者实体:

namespace WebsiteBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Author
{
    /**
     * @Assert\NotBlank
     * @Assert\Length(min = 4)
     */
    protected $firstname;

    /**
     * @Assert\NotBlank
     */
    protected $lastname;

    /**
     * @Assert\Valid
     */
    protected $address;

    /**
     * @return mixed
     */
    public function getFirstname()
    {
        return $this->firstname;
    }

    /**
     * @param mixed $firstname
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;
    }

    /**
     * @return mixed
     */
    public function getLastname()
    {
        return $this->lastname;
    }

    /**
     * @param mixed $lastname
     */
    public function setLastname($lastname)
    {
        $this->lastname = $lastname;
    }

    /**
     * @return mixed
     */
    public function getAddress()
    {
        return $this->address;
    }

    /**
     * @param mixed $address
     */
    public function setAddress(Address $address)
    {
        $this->address = $address;
    }


}

地址实体:

namespace WebsiteBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Address
{
    /**
     * @Assert\NotBlank()
     */
    protected $street;

    /**
     * @Assert\NotBlank
     * @Assert\Length(max = 5)
     */
    protected $zipCode;

    /**
     * @return mixed
     */
    public function getStreet()
    {
        return $this->street;
    }

    /**
     * @param mixed $street
     */
    public function setStreet($street)
    {
        $this->street = $street;
    }

    /**
     * @return mixed
     */
    public function getZipCode()
    {
        return $this->zipCode;
    }

    /**
     * @param mixed $zipCode
     */
    public function setZipCode($zipCode)
    {
        $this->zipCode = $zipCode;
    }


}

这就是我现在所得到的:

Firstname

     This value should not be blank.

Lastname

    This value should not be blank.

Street
Zipcode

所以:主要实体已经过验证,但是继承的(街道/邮政编码)被“忽略”了..

如何验证(使用此方法,而不是创建自定义验证)子实体?

由于

3 个答案:

答案 0 :(得分:4)

street中的zipcodeAuthorRegistrationType字段与您的Address实体无关。你这样做的原因是什么?我会为您的Address实体创建一个单独的表单类型:

namespace WebsiteBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class AddressType extends AbstractType
{
    protected function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('street', TextType::class)
            ->add('zipCode', TextType::class)
        ;
    }
}

然后您可以将其嵌入AuthorRegistrationType

namespace WebsiteBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;

class AuthorRegistrationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add("firstname")
            ->add("lastname")
            ->add("address", AddressType::class)
            ->add('save', SubmitType::class);
    }
}    

答案 1 :(得分:0)

在您的实体Author中,您有一个属性address,这是另一个实体Address。在我看来,这被称为嵌入式实体,而不是继承。但是,我不是母语为英语的人,所以我可以保证。

问题出在您的实体Author中:

/**
 * @Assert\Valid
 */
protected $address;

这将验证字段本身,但不验证实体street中的字段zipCodeAddress。要实现这一点,您应该告诉验证遍历实体Address并在那里查找验证:

/**
 * @Assert\Valid(
 *    traverse = true
 * )
 */
protected $address;

这应该可以胜任。

编辑:

在您的示例中,我无法立即看到这两个实体之间的关系。现在我看到Author只能有一个Address。这意味着上面建议的代码不会为您完成工作。只有在Author有一个字段address是一个集合的情况下才有必要,即一个作者可以有多个地址。

答案 2 :(得分:0)

xabbuh是对的:

我在控制器中添加了以下内容:

$address = new Address();
$author->setAddress($address);

$form = $this->createForm(AuthorRegistrationType::class, $author, array(
        'required' => false
)); 

在AddressType:

public function configureOptions(OptionsResolver $resolver)
{

    $resolver->setDefaults(array(
        'data_class' => 'WebsiteBundle\Entity\Address'
    ));
}

它有效!