Symfony Form 的数据绑定功能是非常强大和方便的. 在之前的测试中已经体现出来. 表单依据对象属性来创建, 表单提交后, 数据自动绑定到对象属性中. 这里有个小细节就是 Form 是通过对象的 Setter 方法来绑定数据到对象的. 这个地方对严谨的代码会引起异常. 这个在之前的已经有提到过. Symfony4 表单验证 NULL 异常处理
在表单的使用过程中, 不同的框架对 Form 的指南有所不同, 在 Symfony 的用户指南部分, 对表单的简单介绍是通过自动绑定数据来介绍 Form 的功能. 在其他框架 比如: Zend Framework 来说. 则是比较单纯的表单使用介绍. 从 Symfony 的官方表单指南来讲, 这个是值得讨论的地方.
-
使用 Form 的数据自动绑定模式
优点
: 这种模式很方便, 对简单的表单和数据处理简洁.
缺点
: 和对象关联的非常紧密, 如果对象定义被修改, 会涉及到 Form. -
不使用 Form 的数据绑定模式
优点
: Form 的定义会更加的随意性, 独立维护, 不受绑定的对象约束.
缺点
: Form 的数据需要手动的绑定到对象中去.
个人更推荐不使用 Form 的数据绑定模式, 如果一个 Form 设计到多个数据对象的更方便使用. 并且日常的项目中, 数据和业务逻辑的开发是分开的. Entity 等这种对象是会被工程师经常修改的. 如果 Form 类和此类的对象进行了绑定, 修改可能会导致 Form 异常.
我们来修改一下 UserType
类, 让它脱离和 User
类的数据绑定.
- 先去掉
src/Entity/User.php
中的验证声明. 让 User Entity 看起来更纯粹.
- 把表单的验证约束定义到表单类中. 继续修改
src/Form/UserType.php
add('email', EmailType::class, [
'empty_data' => '',
'constraints' => [
new NotBlank(['message' => 'Emaill address cannot be empty.']),
new Email(['message' => 'This email is not a valid email address.'])
]
])
->add('passwd', PasswordType::class, [
'empty_data' => '',
'constraints' => [
new NotBlank(['message' => 'Password cannot be empty character.']),
new Length([
'min' => 4,
'max' => 12,
'minMessage' => 'Your password must be at least {{ limit }} characters long',
'maxMessage' => 'Your password cannot be longer than {{ limit }} characters',
])
]
])
->add('name', TextType::class, [
'empty_data' => '',
'constraints' => [
new NotBlank(['message' => 'Your name cannot be empty.']),
new Length([
'min' => 2,
'max' => 12,
'minMessage' => 'Your name must be at least {{ limit }} characters long',
'maxMessage' => 'Your name cannot be longer than {{ limit }} characters',
])
]
])
->add('save', SubmitType::class)
;
}
}
- 在控制器中, 手动进行数据绑定.
public function signUp(Request $request)
{
//创建用户注册表单对象
$form = $this->createForm(UserType::class);
//监听表单请求
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//提取表单数据.
$data = $form->getData();
//绑定数据到用户对象
$user = new User();
$user->setName($form->get('name')->getData());
$user->setEmail($form->get('email')->getData());
$user->setPasswd($form->get('passwd')->getData());
$user->setExpired(new \DateTime());
$user->setResetPasswdExpired(new \DateTime());
$user->setCreated(new \DateTime());
//持久化到数据库
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('url_home');
//dump($user);
} else {
dump($form->getErrors());
}
return $this->render('default/sign-up.html.twig', [
'form' => $form->createView(),
]);
}
如此, 用户对象发生改变的时候, 对 Form 的影响是非常少的. 也便于开发 Form 的同学维护和重复利用.