Once again I'm answering my own question.
The "magic" is gone from ZF2, we need to fix things ourselves. This is how I did it:
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); } } }
The key is the addHttpMethodHandler() method in the AbstractRestfulController class. With this we can override which controller function is being run for a specific HTTP method. In this case I'm overriding the POST method to call my handlePostPut() function instead. In that function I'm checking whether my "magic" query parameter is present, and if so I'm just doing what the controller would have done if it was a put request. Otherwise I'm treating it as a normal POST request.
There is one caveat though: The action parameter in the RouteMatch object will be set to post even if we're treating it as a put. I don't know of a good way to fix that at the moment.