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 which php://input
is suitable for the task in question.
php://input
is a read-only stream that allows you to read raw data from the request body.php://input
is not available with enctype="multipart/form-data".
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://input
stream, in raw format (string). The information can later be read from it by calling StreamInterface::getContents
, StreamInterface::__toString
, or StreamInterface::read
(which would probably make use of stream_get_contents()
, or similar, in their implementation).
Note: The method StreamInterface::__toString
is automatically called when the object representing the message body, e.g. the instance of the class implementing StreamInterface
is cast to a string. For example, like this - see Type Casting in PHP:
$messageBodyObject = $request->getBody(); // implements StreamInterface
$contentOfMessageBody = (string) $messageBodyObject; // cast to string => StreamInterface::__toString is called
echo $contentOfMessageBody;
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 ServerRequestInterface
only.
The parsed body (read the comments of ServerRequestInterface::getParsedBody
and ServerRequestInterface::withParsedBody
) is thought as a representation in a "parsed" form (array, or object) of the raw data (a string) saved in the php://input
stream 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-Type
is application/x-www-form-urlencoded
(for example when submitting a normal HTML form), the content of the request body is automatically saved into both the php://input
stream (serialized) and the $_POST variable (array). So, in the PSR-7 context, calling both StreamInterface::getContents
(or StreamInterface::__toString
, or StreamInterface::read
) and ServerRequestInterface::getParsedBody
will return "valid" values.
If a POST request is performed and the header Content-Type
is multipart/form-data
(for example when performing a file(s) upload), the content of the request body is NOT saved into the php://input
stream at all, but only into the $_POST variable (array). So, in the PSR-7 context, only calling ServerRequestInterface::getParsedBody
will return a "valid" value.
If a POST request is performed and the header Content-Type
has other value than the two presented above (for example application/json
, or text/plain; charset=utf-8
), the content of the request body is saved only into the php://input
stream. So, in the PSR-7 context, only calling StreamInterface::getContents
(or StreamInterface::__toString
, or StreamInterface::read
) will return a "valid" value.
Resources:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With