如何在ZF2中模拟PUT表格?

时间:2014-10-31 12:47:15

标签: php rest zend-framework2

我正在使用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吗?

2 个答案:

答案 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。我现在还不知道解决这个问题的好方法。