PHP manual states that a stream opened with php://input support seek operation and can be read multiple times as of PHP 5.6, but I can't make it work. The following example clearly shows it doesn't work:
<!DOCTYPE html>
<html>
<body>
<form method="post">
<input type="hidden" name="test_name" value="test_value">
<input type="submit">
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$input = fopen('php://input', 'r');
echo 'First attempt: ' . fread($input, 1024) . '<br>';
if (fseek($input, 0) != 0)
exit('Seek failed');
echo 'Second attempt: ' . fread($input, 1024) . '<br>';
}
?>
</body>
</html>
Output:
First attempt: test_name=test_value
Second attempt:
php://input stream was
- successfully read
- successfully rewinded (fseek succeeded)
- unsuccessfully read
Am I doing something wrong?
Another approach might be to open the input stream each time instead of rewinding and seeking.
If the resource cost won't a problem.
Also there's
file_get_contents
if you're sending json.
With the amount of exceptions and lack of portability using
php://input
I'd recommend you to read the stream and save it to another stream to avoid unexpected behaviour.You can use
php://memory
in order to create a file-stream-like wrapper, which will give you all the same functionality thatphp://input
should have without all of the annoying behaviour.Example:
Additionally you can create your own class to refer to this object consistently:
Usage:
Usage (read all):