zendframework / zend-diactoros

PSR-7 HTTP Message implementation
BSD 3-Clause "New" or "Revised" License
1.56k stars 152 forks source link

Parsing data from PUT method in ServerRequestFactory #144

Closed rougin closed 7 years ago

rougin commented 8 years ago

Hello! Is there a way parse data from PUT method? As I check from PSR-7, to get data from GET method, getQueryParams is called while for POST method is getParsedBody. Thanks in advance!

As for now, to get me going, I'm using this snippet below and changing the Content-Type header to application/x-www-form-urlencoded as a workaround:

parse_str(file_get_contents('php://input'), $parameters);
cdekok commented 7 years ago

Would be nice if this is implemented, I suppose the PSR interface would need an addition to as it now specifically mentions POST requests and not PUT requests, it would avoid adding middleware as.

    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
    {
        $contentType = $request->getHeader('content-type');
        if ($request->getMethod() === 'PUT' && in_array('application/x-www-form-urlencoded', $contentType, true)) {
                $body = [];
                mb_parse_str((string)$request->getBody(), $body);
                $request = $request->withParsedBody($body);
        }

        return $delegate->process($request);
    }

And therefore making the handlers incompatible in applications which do not use this middleware.

weierophinney commented 7 years ago

Parsing the incoming body is non-trivial, and fairly easy to get wrong; it's also not something you want to do if you end up being unable to handle the incoming request.

As such, we recommend handling this via middleware. The zendframework/zend-expressive-helpers package provides an implementation via its BodyParamsMiddleware. Usage then becomes something like:

$app->put('/user/{id:\d+}', [
    BodyParamsMiddleware::class,
    UserUpdateMiddleware::class,
], 'user.update');
ozzpy commented 5 years ago

put $app->pipe(BodyParamsMiddleware::class); in your pipeline, I use as the first middleware loaded. then I can get data using $request->getParsedBody()