php – 级联验证不能在表单的第三层工作

前端之家收集整理的这篇文章主要介绍了php – 级联验证不能在表单的第三层工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个3层的形式:
第一层是游戏的容器:
class GameListType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder,array $options) {
        $builder->add('games','collection',array(
            'required' => false,'allow_add' => true,'prototype' => true,'by_reference' => false,'type' => new GameBetType(),))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'cascade_validation' => true,));
    }  
}

第二层是游戏本身,因为我不打算改变游戏,而是打赌,它只包括下注的形式:

class GameBetType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder,array $options) {   
        $builder->add('bet',new BetType());
    }

    public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'data_class' => 'Strego\TippBundle\Entity\Game','cascade_validation' => true,));
    }  
}

第三层是下注的形式:

class BetType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
    {

        $builder->add('scoreT1','text')
                ->add('scoreT2','text');
        ;
    }


        public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        $resolver->setDefaults(array(
            'data_class' => 'Strego\TippBundle\Entity\Bet',));
    }

}

问题是,如果第三级有验证约束,根表单总是有效的,但是如果我具体验证了下注实体,我的控制器中会得到正确的违规列表:

// Form processing
$form = $this->createForm(new GameListType(),$entity);
$request = $this->getRequest();

if ($request->getMethod() == 'POST') {
    $form->bind($request);
    $entity = $form->getData();

    if ($form->isValid()) {
        foreach ($entity->getGames() as $game) {                  
            if($game->hasBet()){
                $bet = $game->getBet();
                $bet->setUser($user);
                $validator = $this->container->get('validator');
                $errors = $validator->validate($bet);
                var_dump($errors)  //<-- i see there are errors
                if(count($errors) == 0){
                    print($bet. ' gets persisted<br>');
                    $em->persist($bet);
                } 
            }             
        }
    $em->flush();
    }
}

另一个问题是,即使我不调用$em-> persist($bet),实体就会被持久化.我看不到输出中描述的输出

print($bet.'gets persisted<br>');

但表单输入仍然保留在数据库中.

所以我的两个问题:

>如果验证失败,如果赌注失败,我如何得到错误(我不希望整个表单无效,因为3个赌注中只有1个无效).
即使我不叫$em-persist($bet),为什么这个赌注持续下去,这是绑定发生的一些魔法吗?

为了回答您的第二个问题,您可能已经声明用户和投注实体之间的双向OneToMany关系,并在关系的用户端设置cascade = {“persist”}.所以实体管理器会在下一个刷新操作中自动标记Bet实体对象进行插入/更新.还要移动$em-> flush();排出了循环.由于flush方法发出db查询,所以每次代码进入循环时都会连接到db.而如果$em-> flush();在该循环之外,实体将在一个事务中包含所有更改的SQL查询一次.

猜你在找的PHP相关文章