Scenario 1 sending x-www-form-urlencoded data
POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar
Running print_r($request->getParsedBody()); returns fine:
Array
(
[foo] => bar
)
Running print_r($request->getBody()->getContents()); returns a string foo=bar
Scenario 2 sending application/json data
POST /path HTTP/1.1
Content-Type: application/json
{
"foo": "bar"
}
Running print_r($request->getParsedBody()); returns an empty array. Array ( )
But, running print_r($request->getBody()->getContents()); returns fine:
{"foo":"bar"}
Is this expected behavior?
Meaning, if we're sending x-www-form-urlencoded data, we should use getParsedBody().
While getBody()->getContents() should be used if we're sending application/json?
Additional info:
Request object is created using:
$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
Message body:
In a PSR-7 library, the message body is abstracted by the
StreamInterface. Any implementation of this interface MUST wrap a PHP stream and, of course, should provide the proper functionality to perform the specific read/write/seek operations on it. PHP provides a list of I/O streams, from whichphp://inputis suitable for the task in question.In this context, when a request to the server is performed, the request body data (regardless of its data type) is automatically written to the
php://inputstream, in raw format (string). The information can later be read from it by callingStreamInterface::getContents,StreamInterface::__toString, orStreamInterface::read(which would probably make use ofstream_get_contents(), or similar, in their implementation).Note: The method
StreamInterface::__toStringis automatically called when the object representing the message body, e.g. the instance of the class implementingStreamInterfaceis cast to a string. For example, like this - see Type Casting in PHP:Parsed body:
In regard of the PSR-7, the parsed body is a "characteristic" of the applications where PHP is "used as a server-side application to fulfill HTTP requests" (in comparison with the applications where PHP is used as "an HTTP client") - see Summary of the PSR-7 Meta Document. So, the parsed body is a component of the
ServerRequestInterfaceonly.The parsed body (read the comments of
ServerRequestInterface::getParsedBodyandServerRequestInterface::withParsedBody) is thought as a representation in a "parsed" form (array, or object) of the raw data (a string) saved in thephp://inputstream as the result of performing a request. For example, the $_POST variable, which is an array, holds the parsed body of a POST request, under the conditions presented bellow.Relevant use-cases:
If a POST request is performed and the header
Content-Typeisapplication/x-www-form-urlencoded(for example when submitting a normal HTML form), the content of the request body is automatically saved into both thephp://inputstream (serialized) and the $_POST variable (array). So, in the PSR-7 context, calling bothStreamInterface::getContents(orStreamInterface::__toString, orStreamInterface::read) andServerRequestInterface::getParsedBodywill return "valid" values.If a POST request is performed and the header
Content-Typeismultipart/form-data(for example when performing a file(s) upload), the content of the request body is NOT saved into thephp://inputstream at all, but only into the $_POST variable (array). So, in the PSR-7 context, only callingServerRequestInterface::getParsedBodywill return a "valid" value.If a POST request is performed and the header
Content-Typehas other value than the two presented above (for exampleapplication/json, ortext/plain; charset=utf-8), the content of the request body is saved only into thephp://inputstream. So, in the PSR-7 context, only callingStreamInterface::getContents(orStreamInterface::__toString, orStreamInterface::read) will return a "valid" value.Resources: