我正在使用FOSRestBundle在Symfony中构建REST API,我偶然发现了一个似乎微不足道的问题,但我找不到一个好的解决方案。
我想创建一个处理PATCH请求的控制器方法:
/**
* @param Article $article
* @param Request $request
*
* @Patch("/articles/{slug}")
* @ParamConverter("article", converter="doctrine.orm")
*
* @return Response
*/
public function patchAction(Article $article, Request $request)
{
$form = $this->createForm(new ArticleType(), $article);
$form->handleRequest($request);
if ($form->isValid()) {
$entityManager = $this->get('doctrine.orm.entity_manager');
$entityManager->merge($article);
$entityManager->flush();
$view = $this->view($article)
->setTemplate('MyBundle::articleSubmit.html.twig')
->setTemplateVar('article')
;
return $this->handleView($view);
}
$view = $this->view($form)
->setTemplate('MyBundle::articleForm.html.twig')
->setTemplateVar('form')
->setTemplateData(array('article' => $article))
;
return $this->handleView($view);
}
我已经配置了这样的表单类型,将method
选项设置为PATCH
:
namespace MyBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ArticleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('content', 'textarea');
}
public function getName()
{
return '';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Article',
'method' => 'PATCH',
));
}
}
当我想看到这个工作时,只要我发出真正的PATCH
请求(例如使用Open HttpRequester),一切都会顺利进行。但由于大多数浏览器仅支持GET和POST方法,Symfony会将_method
参数添加到常规POST
请求中,这就是我的问题开始的地方,因为在浏览器中测试时我收到消息:< / p>
此表单不应包含额外字段。
这显然是因为ArticleType::getName()
返回空字符串,但我希望我的请求参数看起来更像content=foo
而不是article[content]=foo
,就像它在REST API中所假设的那样。这就是为什么我希望这个方法返回空值。
当我将操作更改为POST
,或者设置表单的名称,或者我发出真正的PATCH
请求时,这通常会正常工作,但在我发送{{{ 1}}请求POST
参数。
我设法解决了这个问题,创建了一个body listener来删除名称前缀为_method
的字段,但这更像是一个肮脏的黑客,而不是一个漂亮而干净的解决方案。
我确信必须有一些更好的解决方法,请提前感谢您的帮助。