PHP $_POST array empty although php://input and raw post data is available?

I just helped a friend get through a devious issue with his PHP installation that I thought i’d blog about. There are other posts discussing problems related to having a $_POST array be completely empty although reading POST data directly via php://input wrappers works.

I used a similar test file to try and determine what was happening in the first place:



<?php
print "CONTENT_TYPE: " . $_SERVER['CONTENT_TYPE'] . "<BR />";
$data = file_get_contents('php://input');
print "DATA: <pre>";
var_dump($data);
var_dump($_POST);
print "</pre>";
?>
<form method="post">

    <input type="text" name="name" value="ok" />
    <input type="submit" name="submit" value="submit" />

</form>

If you submit the form and you see this as the result:



CONTENT_TYPE: application/x-www-form-urlencoded
DATA:

string(21) "name=ok&submit=submit"
array(0) {
}

… then that means that your browser is correctly submitting the right CONTENT_TYPE, and is also sending the browser POST data correctly. PHP is also seeing the right raw post data via the raw POST input wrapper, but the $_POST superglobal is totally empty.

What this eventually got tracked down to was an update in the php.ini that changed post_max_size from “8M” to “10MB”. Did you catch that? The use of “MB” instead of “M” was invalid, but instead of throwing an error on startup, PHP internally interpreted this as a “0” since it was invalid. Since the post_max_size was effectively zero, nothing made it into the $_POST array.

Hope this helps anyone else debugging a similar issue! Oh, and hopefully it goes without saying, make sure you delete this test file as soon as you’re done, but it’s a giant XSS hole waiting to happen.

26 thoughts on “PHP $_POST array empty although php://input and raw post data is available?

  1. You sir are a gentleman and a scholar.

    This was exactly the problem I was having. I modified my php.ini months ago and must have never noticed that POST didn’t work after that, it was only today when I went to write a quick script that relied on POST data and found that it wasn’t working.

    Thank you!

  2. I was running into a blank POST array today, but turns out that the reason mine was empty was that my postmaxsize variable in php.ini was set to higher than the amount of physical RAM in the machine.

    Thanks for the script, It helped me debug the issue.

  3. I just had the same, problem but opposite cause. Under PHP 5.3.0 I had to change from “200MB” to “200M” and it worked. Ridiculous. Thanks for the tip, though, it put the idea in my head to try it!

  4. Cesar: good point. This is the type of thing that Firebug is really handy for – if you can see via the Net panel that it’s following a 302 redirect instead of sending a POST payload, you should be able to figure out what’s going on pretty quickly.

  5. Hi guys, I had a slightly different problem, however this post helped me to find a solution, and here it is.

    Your test example was working on my machine but my real form was still not submitting anything (I was submiting one form to another). My php.ini was correctly configured so it had to be something else.

    One reason was that my submit button didn’t have valid name attribute and value – it has to have one name attribute and its value has to be without underscores, for example like this: name=”submit” and not name=”submitbtn” (as described, for example, here: http://hr.php.net/manual/en/tutorial.forms.php, comment from arnelmilan).

    The other reason was my login and password fields also not having name atributes, so I added them as well, also without underscores, for example, name=”login”, name=”password”.

    I guess I was used to use “id” attributes instead of “name” (since I am not really a php programmer, but a .net one).

    I hope this helps someone with similar problem.

    Cheers!

  6. Hi, I know this post is almost a year old but I am hoping someone can help me. I have a similar problem: The contents of the $POST variable is incomplete. Outputting data via “php://input” gives me the correct data, however vardumping the $POST variable shows a cutoff array… Does anyone have an idea why this is happening? (BTW: postmax_size is correctly set and its value is 8M)

  7. @Luis

    Hi, I just found my solution on http://bugs.php.net/bug.php?id=22427 In my case, I just disabled the suhosin extension. Hope this helps.

    [2007-10-30 10:02 UTC] sbauer at gjl-network dot net

    While experiencing this issue, too we found that the cause of this problem was the suhosin patch, wich was – by default – configured to have a max limit for the length of cookie, request, post, get and session vars. E.g. for POST this looks like:

    suhosin.post.maxarraydepth 100 100 suhosin.post.maxarrayindexlength 64 64 suhosin.post.maxnamelength 64 64 suhosin.post.maxtotalnamelength 256 256 suhosin.post.maxvaluelength 65000 65000 suhosin.post.maxvars 200 200

    Those derivatives needs to be set to a adequate higher number. E.g. in our case, the problem was, that our POST data was too long (as this seems to be the case for a lot of you here).

    So I suggest to check your php.ini or (according to your distribution there often is a suhosin.ini) and correct the above values or set them to 0 to disable it. If those derivatives are not set, default values will be used. You need to check / add: suhosin.post.max…. suhosin.request.max… suhosin.get.max… suhosin.session.max… suhosin.cookie.max_…

    Refer to your phpinfo() where these values should be listed!

  8. Hey,

    I have the same problem with POST method, tried all options in this thread and other forums too, but could not get it work.

    Here is my code: <?php

    $data = filegetcontents(‘php://input’); print(“Data is : “); print_r($data);

    print “CONTENTTYPE: ” . $SERVER[‘CONTENTTYPE’] . “”; $data = filegetcontents(‘php://input’); print “DATA:

    ";
    var
    dump($data); vardump($POST); print "“; ?>

    The output is: Data is :

    CONTENT_TYPE: DATA:

    string(0) “” array(0) { }

    Can anybody help me on this?

    Massam

  9. @Vincent

    how to disable suhosin setting from php.ini or suhosin.ini

    i have made the changes in .htaccess php_flag suhosin.simulation Off but still not working ..

  10. I have the same problem. The question is, what should I do to solve it? The test run you shared does not return the same results as you indicated. It is stressing the heck out of me and please help me fix this!

  11. Please help me to find the error on this code as when i run this code i get the result as Warning: Division by zero.. When i run this query inside localhost/phpmyadmin it doesn’t when i run on the page Please help me to find the error

  12. My method=”POST” wasn’t working for new pages. Existing pages (or the ones I transferred when setting up IIS7.5 with SSL would work). Querystring name/values would work. Tore out all my hair. Then I pasted the whole URL path into the form action=”https://www.yadayada.com” and it worked! go figure. So I went and in IIS7.5 I right clicked on the Application Pool and picked “Recycle” and then the new pages worked without the full path. Just something for someone where nothing else worked. Server was a virtual box and I suspected the pages needed some “curing” or something like fine wine. Recycling application pool did the job.

  13. Just been hunting this problem down. After reading this page, I checked the postmaxsize which was set to 16 with no units. Same effect!

    Thanks you saved my bacon!

Comments are closed.