Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

[Question] $request->getParsedBody() returns empty array using PUT/PATCH methods #371

Open
gabbydgab opened this issue Aug 18, 2016 · 16 comments
Labels

Comments

@gabbydgab
Copy link

I'm having difficulty in parsing the $request->getParsedBody() for PUT/PATCH method - it only returns empty array.

I've enabled Body Parsing Middleware on my controller and it works with POST method.

https://docs.zendframework.com/zend-expressive/features/helpers/body-parse/

I'm trying to implement the REST Controller by Alejandro Celaya

https://blog.alejandrocelaya.com/2016/06/24/dispatch-rest-like-requests-with-a-single-controller-class-in-zend-expressive/

Appreciate your input here. Thanks in advance.

@gabbydgab gabbydgab changed the title [Question] $request->getParedBody() returns empty array using PUT/PATCH method [Question] $request->getParsedBody() returns empty array using PUT/PATCH methods Aug 18, 2016
@gabbydgab
Copy link
Author

I've tried to use $request->getBody()->getContents() and it shows the body params in string format. I don't know why the getParsedBody() returns an empty array.

You may try this: https://gist.github.com/gabbydgab/0193c4b6a8e02f658e9b5f7b7650235d

@gabbydgab
Copy link
Author

It seems it only works with application/json type.

See zendframework/zend-expressive-helpers#19

@geerteltink
Copy link
Member

From the docs (the first link you gave):

Body Parsing Middleware

By default, this middleware will detect the following content types:

  • application/x-www-form-urlencoded (standard web-based forms, without file uploads)
  • application/json, application/*+json (JSON payloads)

@loter
Copy link

loter commented Sep 20, 2016

Even using the body parsing middleware, on POST request the getParsedBody() is not empty, but when PUT request is sent, it's always empty for some reason.

@michaelmoussa
Copy link
Contributor

@gabbydgab Which version of zend-expressive-helpers are you using? There was a fix pertaining to JSON requests and parsed body in 2.0.1 (which was released after you opened this issue) that may be related. You might want to check on that as well, @loter.

If that's not the issue, let me know and we can investigate further.

@geerteltink
Copy link
Member

@michaelmoussa Ah, that would make sense since I can't replicate it. I should read the changelogs more often :)

@ezimuel
Copy link
Contributor

ezimuel commented Sep 20, 2016

@gabbydgab The getParsedBody() works only with GET/POST for application/x-www-form-urlencoded. XHTML 1.x forms only support GET and POST.
That said, you can also use PUT with x-www-form but you need to parse data using php://input source, because there isn't a $_PUT global. Here you can read an article on how to implement it.

@ezimuel ezimuel closed this as completed Sep 20, 2016
@weierophinney
Copy link
Member

Actually... this should work. For people this affects, we need the following information:

  • What is the value of the Content-Type header?
  • What HTTP request method were you using?
  • What was the body content provided by the client?
  • What does (string) $request->getBody() return?

@weierophinney weierophinney reopened this May 3, 2017
@weierophinney
Copy link
Member

@ezimuel has indicated that he encountered the problem with Content-Type: application/json; charset=utf-8. This makes sense that it would fail at this time, as our matching is for the pattern #[/+]json$# currently. This should likely be updated to split the content-type at a ; boundary:

$parts = explode(';', $contentType, 2);
$contentType = $parts[0];
// perform match

@ezimuel Would you like to prepare a PR? If not, I'll do it next week.

@harikt
Copy link
Contributor

harikt commented May 4, 2017

@lvidal1
Copy link

lvidal1 commented May 6, 2017

Unfortunately, when I send JSON using POST/PUT request and then do $request->getParsedBody(), I get an empty array(), too.

My scenario in POSTMAN:

  1. I use {"Content-Type":"application/json"}
  2. It happens on POST / PUT / PATCH request
  3. I send a simple JSON structure like {"email":"email21@gmail.com","password":"1234"}
  4. When I do (string) $request->getBody() gets the actual json in string format, and also I implemented an function in my AbstractController to handle the raw body like this:
    (array)json_decode($request->getBody()->getContents());which I consider a rustly way to parse JSON having the getParsedBody(). Does anyone has an update on this?

@weierophinney
Copy link
Member

@harikt Ooof, you're right. I'll still work up a PR with at least the failing test, though, as it's not working. Something's amiss.

@lvidal1 — One issue with getContents() is that it grabs contents from the current pointer. So, if the pointer is already at the end, you'll get an empty string. As such, you should likely either do a $body->rewind() first, or just cast getBody() to a string.

weierophinney added a commit to weierophinney/zend-expressive-helpers that referenced this issue May 8, 2017
Creates an integration test to attempt to recreate the problem reported
in zendframework/zend-expressive#371. It sets up the following
conditions:

- A request method that can provide body content
- A request body with JSON content
- A `Content-Type` request header with the value `application/json;charset=utf-8`

It then passes the request to the `BodyParams` middleware, and validates
that the request received by the delegate has the parsed contents.

Unfortunately... it does not validate the issue reported, as the test
passes.
@weierophinney
Copy link
Member

I've created a unit test intended to reproduce the issue... but it doesn't. It passes. If this issue affects you, please look at zendframework/zend-expressive-helpers#43, and let me know if any changes need to be made to the tests proposed.

@jbelien
Copy link
Contributor

jbelien commented Mar 15, 2018

Well, I'm really happy to have discovered this thread !

I was really struggling with $request->getParsedBody(), it was always empty when (string)$request->getBody() was not empty (exactly as described by @lvidal1 : #371 (comment)).

Following zendframework/zend-expressive-helpers#43, I added Zend\Expressive\Helper\BodyParams\BodyParamsMiddleware::class in my pipeline and now it works just fine ! 🎉

@ramsey
Copy link

ramsey commented May 28, 2019

Thank you for this thread! It took me forever to figure out that I needed to add BodyParamsMiddleware to my pipeline. I spent about 3 days racking my brain over this until tracing through and figuring out that $request->getParsedBody() was the culprit, returning an empty array.

@weierophinney
Copy link
Member

This repository has been closed and moved to mezzio/mezzio; a new issue has been opened at mezzio/mezzio#17.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

10 participants