Slim 3 Request Content Type

The encoding type of your request matters. In Slim 3 we try to support a wide variety of different formats to make sure you don't have to. I want to take some time to demystify how this process works. Let's take a look.

Developers often overlook encoding on form submissions, blissfully unaware that the default encoding type is application/x-www-form-urlencoded. It becomes a problem when developers are interested in building APIs. Typically when I build an API i like to use application/json, because JSON is just so wonderful to work with. However tools like google chrome's extension POSTMAN can be a bit unweildy for some, so I hope to cover off a bit of Slim internals and how the encoding type is handled and why it is that way.

First off I want to talk about what PHP does and doesn't do. As we all know PHP has 2 very helpful superglobals $_GET, $_ POST. What you might not realize is that there is no $_PUT or $_HEAD or $_PATCH, or any other HTTP Verb. WTF?!?! Well what does slim do? Well Slim handles this for you, via Media Parsers and reading php://input directly. The media parsers have different strategies on how to decode/parse the actual request body with is retrieved through php://input.

Let's take a look at what a request looks like.

PUT /user/1 HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.example.com
Content-Type: application/json; charset=utf-8
Content-Length: 88
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
{ "username" : "abc" }

In the above we see a PUT request that sets a new username to user/1. Slim will automatically parse this request body because it knows what to do with application/json. Tracing through the Request's class code shows that the parsedBody is not set until you try and access the body message the first time. https://github.com/slimphp/Slim/blob/3.x/Slim/Http/Request.php#L959-L984

Accessing the parsed body's username key will result in the expected "abc".

$username = $request->getParsedBody()['username'];
//$username = "abc";

Default Media Parsers

  • application/x-www-form-urlencoded
  • text/xml
  • application/xml
  • application/json
  • POST ONLY ['multipart/form-data']

Please note that text/json IS NOT HANDLED BY DEFAULT. I am working on getting that changed ;)

If you find yourself with a blank parsed body, do check your Content-Type header and make sure that its one supported by Slim.

I hope this helps you out!

o7 Happy Coding

Written by Glenn Eggleton on Tuesday February 2, 2016
Permalink - Chapter: Slim