Symfony控制器数据库更新问题:如何依据查询参数将参与者的'etat'字段更新为1
问题分析与修复方案
我一眼就看出你代码里的核心问题了:你成功从数据库检索到目标Participants实体$participant后,却新建了一个完全无关的全新Participants对象$part来修改etat值,最后反而去持久化刷新原来的未修改对象,这当然不会有任何数据库更新啦!
修正后的代码
/** * @Route("/acceptation", name="acceptation") */ public function acceptation(Request $request, EntityManagerInterface $em, ValidatorInterface $validator):Response { $idU = $request->get('idUtilisateur'); $nom= $request->get('nomTontine'); $participant = $this->getDoctrine()->getRepository(Participants::class)->findOneBy(['idUtilisateur'=> $idU , 'nomTontine'=> $nom]) ; if( $participant) { // 直接修改从数据库加载的实体对象,不要新建! $participant->setEtat(1); // 注意:Doctrine会自动跟踪已加载的实体,persist()在这里可以省略 // $em->persist($participant); $em->flush(); // 执行flush后,变更才会同步到数据库 } return $this->render('sunutontine/acceptation.html.twig' ,[ 'controller_name' => 'SunuController', ]); }
为什么原来的代码没用?
- Doctrine的实体管理器(EntityManager)会自动跟踪所有从数据库加载的实体对象,当你修改这些对象的属性时,Doctrine会记录下这些变更。
- 你之前新建的
$part是一个从未被Doctrine跟踪的空对象,而且你也没有把它持久化到数据库;同时你刷新的是未做任何修改的$participant,所以数据库里的记录自然不会变。
额外优化建议
如果你想让代码更简洁安全,可以使用Symfony的参数转换器,让框架自动帮你查找实体:
/** * @Route("/acceptation/{idUtilisateur}/{nomTontine}", name="acceptation") */ public function acceptation(Participants $participant, EntityManagerInterface $em):Response { // 如果参数转换器找不到对应的实体,会自动返回404,所以不需要额外判断 $participant->setEtat(1); $em->flush(); return $this->render('sunutontine/acceptation.html.twig' ,[ 'controller_name' => 'SunuController', ]); }
这样你就不用手动写查询代码,还能自动处理实体不存在的情况,代码更优雅~
内容的提问来源于stack exchange,提问作者MMN
相关产品推荐
相关产品推荐

