【发布时间】:2014-11-30 18:55:38
【问题描述】:
我遇到了 Symfony 表单验证问题(使用 Silex)。我有一个密码重置表单的repeated 输入,如果两个密码匹配,它就可以正常工作。但是,如果他们不这样做,$form->isValid() 仍会返回 true。 $form->getErrorsAsString() 也是空的。
经过大量谷歌搜索并阅读了许多或多或少相关的问题的答案后,我仍然没有找到解决方案。
更新:在检查了我的 Git 存储库中的各种版本后,我最终发现当我将 Symfony 从版本 2.5.7 更新到昨天发布的版本 2.6.0 时,该功能损坏了。我查看了更改日志,没有看到任何会破坏这一点的东西。我暂时切换回来,但最终希望能够使用版本2.6.0...
这是为我的PasswordResetType 定义的buildForm 方法:
function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('password', 'repeated', array(
'type' => 'password',
'invalid_message' => $this->app['translator']->trans('form_errors.pass_must_match'),
'required' => true,
'first_options' => array(
'constraints' => array(
new Assert\NotBlank()
),
),
'second_options' => array(
'constraints' => array(
new Assert\NotBlank()
)
)
))
;
}
}
与我的表单关联的 Twig 模板:
{{ form_start(form) }}
{{ form_widget(form._token) }}
{{ form_errors(form) }}
<div class="form-group">
{{ form_label(form.password.first, 'user.new_password'|trans, {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(form.password.first) }}
{{ form_widget(form.password.first, {'attr': {'class': 'form-control', 'placeholder' : 'user.new_password'|trans}}) }}
</div>
<div class="form-group">
{{ form_label(form.password.second, 'user.new_password_confirmation'|trans, {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(form.password.second) }}
{{ form_widget(form.password.second, {'attr': {'class': 'form-control', 'placeholder' : 'user.new_password_confirmation'|trans}}) }}
</div>
<button type="submit" class="btn btn-primary btn-block">{{'user.reset_password'|trans}}</button>
{{ form_end(form) }}
关联的控制器:
$app->get('/{_locale}/reset_password/{token}', function(Request $request, $token) use ($app) {
/* ... */
$form = $app['form.factory']->createBuilder(new PasswordResetType($app), array())->getForm();
return $app['twig']->render('password_reset.twig', array(
'title' => 'Page title',
'form' => $form->createView()
));
})->bind('reset_password');
$app->post('/{_locale}/reset_password/{token}', function(Request $request, $token) use ($app) {
/* ... */
$form = $app['form.factory']->createBuilder(new PasswordResetType($app), array())->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
$password = $data['password']; // this is line 113
/* ... */
}
});
当密码不匹配时,这会生成以下错误:Error: ContextErrorException in controllers_users.php line 113: Notice: Undefined index: password。这表明 $form->isValid() 返回了 true,但它不应该返回,因为密码不匹配。
更新:我打开了一个错误报告:https://github.com/symfony/symfony/issues/12792
【问题讨论】:
-
尝试移除约束,因为它们在那里没有意义
-
好吧,我刚刚找到了起源:当我将 Symfony 从版本
2.5.7更新到版本2.6.0时,它坏了。我暂时切换回来,但希望能够使用新版本。不幸的是,在更新日志中没有看到任何关于此的内容。关于这些限制,我认为'required' => true只会在浏览器中添加属性,但如果我明白你的意思,它也适用于验证器吗?我尝试删除它们,但问题仍然存在。 -
刚刚通过手动删除表单中的
required属性进行了尝试,我的直觉是正确的:那些不做同样的事情。它允许我提交两个字段为空白的表单,因此一个用于浏览器,另一个用于验证器。 -
刚刚在我没有 Silex 的 Symfony 2.6 项目上测试了这个,看起来验证工作正常,我只是使用
createForm()而不是createBuilder() -
我尝试使用
createForm(),但我收到一条错误消息,提示该方法不存在。查看文档,示例始终使用$formFactory->createBuilder()->getForm()。你的代码到底是什么样的?
标签: php forms validation symfony silex