我正在尝试使用Symfony表单来处理REST请求。
我遇到了以symfony形式绑定请求数据的问题。在浏览Symfony的代码时,我发现它使用了
HttpFoundationRequestHandler->handleRequest
在那里,对于POST,
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
如果您看到上面的代码,如果我们的表单类型类中有表单名称,它会尝试从请求中获取值
$ request-> request-> get($ name)// $ name是表单名称。
如果我们将表单呈现为HTML,但是如果我们通过REST发布请求,它可能会有效,但它找不到数据。
为了使它工作,我们要么必须在请求中将其命名为下面的命名空间(我没有亲自测试过,但已在某处读过它)
{
'form_name': {
'field1' => 'value1'
}
}
只有在requst以下才能绑定数据
{
'field1' => 'value1'
}
或者我们必须从表单类型的getName返回表单名为null,以便它使用root命名空间。
public function getName()
{
return null;
}
如果我们返回null,那么它会产生其他问题,如果请求中除了表单字段之外还有任何额外参数,则会产生验证错误。
"This form should not contain extra fields."
理想情况下,表单应该只从请求中获取feild值,这些值在表单中配置,并且应该忽略任何其他不知道的请求参数。
e.g。如果这是表格
class SampleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('field1', 'text', array('constraints' => new NotBlank()))
->add('field2', 'password', array('constraints' => new NotBlank()));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
));
}
public function getName()
{
return null;
}
}
但请求我是否正在发送
{
'field1' => 'value1',
'field2' => 'value2',
'field3' => 'value3'
}
它给出了上述验证错误。理想情况下,它应该简单地忽略field3并获取feild1&来自请求的field2。
如果我们比较NativeRequestHandler& HttpFoundationRequestHandler,
NativeRequestHandler似乎已正确处理
if ('' === $name) {
$params = $_POST;
$files = $fixedFiles;
} elseif (array_key_exists($name, $_POST) || array_key_exists($name, $fixedFiles)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
} else {
// Don't submit the form if it is not present in the request
return;
}
HttpFoundationRequestHandler不在哪里
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
那么要么我们需要能够使用NativeRequestHandler,要么需要在HttpFoundationRequestHandler中修复?
我看到下面的工作,但仅在内容类型文本请求的情况下(不适用于application / json),
$form->submit(array('field1' => $request->request->get('field1'), 'field2' => $request->request->get('field2')))
但是使用$ form-> handleRequest($ request)看起来更简单和抽象。
如果还有其他更好更简单的解决方案,请建议。