Symfony Form如何通过Session存储表单数据并保留筛选条件
问题修复方案
1. 刷新后所有筛选条件丢失的修复
你当前的Controller代码执行顺序完全错误,导致永远只能存空的表单初始值到Session,正确逻辑如下:
public function indexAction(Request $request) { $session = $request->getSession(); $form = $this->createSearchForm(); // 第一步:先从Session读取历史筛选数据预填表单 if ($session->has('form_data')) { $form->setData($session->get('form_data')); } // 第二步:处理本次请求的新筛选参数(包括页面刷新带的GET参数、Ajax提交的参数) $form->handleRequest($request); // 第三步:如果表单提交且验证通过,把最新的筛选数据存入Session if ($form->isSubmitted() && $form->isValid()) { $formData = $form->getData(); // 这里要处理Job实体的序列化问题,见第二个问题的修复 $session->set('form_data', $formData); } // 用最新的表单数据查询数据表 $this->datatable($form->getData()); return $this->render('backend/jobOffer/index.html.twig', [ 'form' => $form->createView() ]); }
2. Select2EntityType字段无法存入Session的修复
问题原因:Select2EntityType对应的值是AppBundle:Job实体对象,PHP Session默认无法直接序列化存储Doctrine实体,会出现序列化失败、字段丢失的问题,两种修复方案可选:
方案一:存储实体ID,读取时自动重建
存Session前把Job实体转成ID存储,读取时再查询数据库赋值:
// 存入Session前的处理 if ($form->isSubmitted() && $form->isValid()) { $formData = $form->getData(); // 把实体转成ID存 $sessionData = $formData; if ($sessionData['job'] instanceof Job) { $sessionData['job_id'] = $sessionData['job']->getId(); unset($sessionData['job']); } $session->set('form_data', $sessionData); } // 从Session读取后的处理 if ($session->has('form_data')) { $sessionData = $session->get('form_data'); if (isset($sessionData['job_id'])) { $sessionData['job'] = $this->getDoctrine()->getRepository(Job::class)->find($sessionData['job_id']); unset($sessionData['job_id']); } $form->setData($sessionData); }
方案二:给Job实体实现Serializable接口
直接让Job实体支持序列化,就可以直接存入Session:
// AppBundle/Entity/Job.php class Job implements \Serializable { // 原有属性和方法不变 public function serialize() { return serialize([ $this->id, $this->label, // 其他需要保留的字段 ]); } public function unserialize($serialized) { list( $this->id, $this->label, // 对应序列化的字段顺序 ) = unserialize($serialized); } }
内容的提问来源于stack exchange,提问作者Thierry
相关产品推荐
相关产品推荐

