Post data in PHP captured in the $_POST and $_FILES super-globals, however if you are dealing with PATCH or PUT method we can’t depend $_POST superglobal. For this PHP 8.4 introduced the request_parse_body() function.
In PHP the $_POST
superglobal store the post data when user submit data using the post
Http verb. However if you are sending data using ajax or sending data to a REST api, you may use other http methods like PUT
, PATCH
and DELETE
. In PHP to capture such data we tend to use php://input
stream wrapper:
Prior to PHP 8.4:
$post = file_get_contents("php://input");
With PHP 8.4 the request_parse_body()
function introduced to manipulate non-post http verbs.
[$_POST, $_FILES] = request_parse_body();
request_parse_body()
return an array where the item at index 0 contain the $_POST
data while item at index 1 contain the $_FILES
data if any.
request_parse_body()
reads the request body and parses it according to the Content-Type
header. Currently, two content types are supported: application/x-www-form-urlencoded
and multipart/form-data
An example ajax request:
request_parse_body_demo.php
<html> <head> <meta charset="utf-8" /> <title>Request parse body demo</title> </head> <body> <form method="post" action="#" enctype="multipart/form-data"> <p> <label>Title</label> <input type="text" name="title" /> </p> <p> <label>Content</label> <textarea name="content"></textarea> </p> <p> <label>Select image</label> <input type="file" name="image" /> </p> <p> <button type="submit" name="submit" id="submit">Submit</button> </p> </form> <script type="text/javascript"> document.querySelector("#submit").addEventListener("click", async function (e) { e.preventDefault(); const formData = new FormData(); formData.append('title', document.querySelector("input[name=title]").value); formData.append('content', document.querySelector("textarea[name=content]").value); // image formData.append('image', document.querySelector("input[name=image]").files[0]); const response = await fetch("./api.php", { method: "PUT", body: formData, }); console.log(await response.json()); }); </script> </body> </html>
In this script we have a simple form that when submitted it makes ajax request to the server using javascript fetch
Api. In the fetch()
function i specified the url to send the data which is “api.php” and specified the method which is PUT
in this case and the body in the form of formData
object.
api.php
<?php var_dump($_POST, $_FILES); ?>
If you run this example and checked the result of dumping the $_POST
and $_FILES
you will get empty arrays as we are using PUT
as the method type in the fetch request
array(0) { } array(0) { }
Using request_parse_body()
:
api.php
<?php try { [$_POST, $_FILES] = request_parse_body(); var_dump($_POST, $_FILES); } catch(RequestParseBodyException) { echo "empty post data"; } ?>
Now by checking the $_POST and $_FILES you will see the dumped data:
array(2) { ["title"]=> string(10) "post title" ["content"]=> string(12) "post content" } array(1) { ["image"]=> array(6) { ["name"]=> string(22) "111473537-240x180.webp" ["full_path"]=> string(22) "111473537-240x180.webp" ["type"]=> string(10) "image/webp" ["tmp_name"]=> string(27) "C:\Windows\Temp\php7B9E.tmp" ["error"]=> int(0) ["size"]=> int(8266) } }
In addition to this the function accepts an $options
array argument that can customize it’s behavior:Â
The $options
 parameter accepts an associative array to override the following global php.ini settings for parsing of the request body.
max_file_uploads
max_input_vars
max_multipart_body_parts
post_max_size
upload_max_filesize
[$_POST, $_FILES] = request_parse_body([ 'post_max_size' => '10M', 'upload_max_filesize' => '10M', ]);