BodyParamsMiddleware oddity

I’ve been a bit perplexed by inconsistent results from BodyParamsMiddleware.

I have it set up in pipeline.php with

$app->pipe(BodyParamsMiddleware::class);

and my handler has a check that it gets the forma data

public function handle(ServerRequestInterface $request) : ResponseInterface
{
    $requestBody = $request->getParsedBody();

    if (empty($requestBody))
    {

If I POST form data to that handler, all is well, but if I use PUT, with nothing changed except the method, it doesn’t get the request body back.

If I submit JSON data instead of form data, it works as expected for both POST and PUT.

I can’t see an obvious reason why it should behave differently for PUT with form data. Am I missing something obvious?

What is the content-type header in each case?

With the form data it’s “Content-Type: multipart/form-data”, with JSON it’s “Content-Type: application/json”.

Body parsing doesn’t work with multipart/form-data out of the box – that’s binary data, like a file post. Are you uploading a file? If not, use application/x-www-form-urlencoded.

I just picked the wrong option in postman and “application/x-www-form-urlencoded” is what I should have used. The odd thing is that it worked for POST, so I expected it to work for PUT as well.

If I remember correct, PUT is not really valid HTML when it comes to form data.If you really need PUT, make it an API call with JSON data. That should get you going.

As I haven’t really worked on web programming for nearly 20 years, I had to go away and Google PUT with form data. It seems to be true to say that a form with METHOD=PUT isn’t valid HTML, but an HTTP PUT with form data is legitimate.

That’s a bit weird.

As I was sending HTTP PUT from Postman initially and eventually will be doing HTTP PUT from Javascript, I don’t expect to have an issue with that.