我正在使用Zend Framework 2实现REST服务。路由和控制器运行良好,但现在我需要在视图中显示更新表单。
在Zend Framework 1中,我可以使用" magic" GET参数?_method=PUT
,这将使ZF认为它实际上是一个PUT请求。这意味着表单标签看起来像:
<form action="/resource/1/?_method=PUT" method="POST">
以上在ZF2中不起作用:不是在我的控制器中运行update()
方法,而是create()
方法被激活。
如何在ZF2中模拟PUT请求?我可以不使用JavaScript吗?
答案 0 :(得分:2)
我认为ZF2根本不像你的那样处理这种情况。你必须自己处理它。请参阅以下代码:
class Module implements BootstrapListenerInterface
{
public onBootstrap(EventInterface $event)
{
$event->getApplication()
->getEventManager()
->attach(MvcEvent::EVENT_ROUTE, function(MvcEvent $e){
$request = $e->getRequest();
$m = $request->getQuery('_method');
switch ($m)
{
case Request::METHOD_PUT:
$request->setMethod(Request::METHOD_PUT);
break;
case Request::METHOD_DELETE:
$request->setMethod(Request::METHOD_DELETE);
break;
case Request::METHOD_POST:
$request->setMethod(Request::METHOD_POST);
break;
case Request::METHOD_GET:
$request->setMethod(Request::METHOD_GET);
break;
default:
break;
}
});
}
}
答案 1 :(得分:1)
我再次回答我自己的问题。
“魔法”从ZF2消失了,我们需要自己解决问题。我就这样做了:
class ResourceController extends AbstractRestfulController
{
public function __construct()
{
$this->addHttpMethodHandler('POST', array($this, 'handlePostPut'));
}
public function handlePostPut($event)
{
$request = $event->getRequest();
if ('put' == strtolower($request->getQuery('_method'))) {
$routeMatch = $event->getRouteMatch();
$id = $this->getIdentifier($routeMatch, $request);
$data = $this->processBodyContent($request);
if ($id !== false) {
return $this->update($id, $data);
}
return $this->replaceList($data);
} else {
return $this->processPostData($request);
}
}
}
关键是addHttpMethodHandler()
类中的AbstractRestfulController
方法。有了这个,我们可以覆盖为特定HTTP方法运行的控制器功能。在这种情况下,我重写POST方法来调用我的handlePostPut()
函数。在那个函数中,我正在检查我的“魔法”查询参数是否存在,如果是,我只是在做控制器如果是put请求就会做的事情。否则我将其视为正常的POST请求。
但有一点需要注意:即使我们将其视为put,RouteMatch对象中的action参数也将设置为post
。我现在还不知道解决这个问题的好方法。