6

I understand that if a POST request exceeds post_max_size, the $_POST and $_FILES superglobals become empty.

I've seen plenty of discussions about how to detect this scenario, but never an explanation of why the superglobals are empty. It seems really odd to me to wipe out the POST data, forcing the user to reenter their answers. Is it a security precaution perhaps?

Curious about other languages (java, .net). Do they behave similarly?

Thanks

regilero
  • 29,806
  • 6
  • 60
  • 99
jbarreiros
  • 1,103
  • 1
  • 10
  • 21
  • 7
    See the accepted answer to [this question](http://stackoverflow.com/questions/2733256/post-data-returns-empty-when-headers-are-post-max-size) – Clive Nov 01 '11 at 17:28
  • it seems really odd to me to see a picture being sent along with text data. – Your Common Sense Nov 01 '11 at 17:32
  • Even the web server itself is likely to have a limitation, e.g. [Apache's LimitRequestBody](http://httpd.apache.org/docs/2.2/en/mod/core.html#limitrequestbody). – Álvaro González Nov 01 '11 at 17:33
  • Thanks @Clive. I read through a dozen stackexchange posts and somehow missed that one. – jbarreiros Nov 01 '11 at 17:58
  • 1
    @ÁlvaroG.Vicario, thanks for the reply. Luckily the default value of LimitRequestBody is unlimited, which I verified is the case on our server setup. – jbarreiros Nov 01 '11 at 17:59
  • 4
    @jbarreiros If you wan't understand *why* the post data is thrown away, do some reading on how multipart MIME messages work, paying particular attention to the `multipart/form-data` type. When `post_max_size` is reached, the server will stop receiving and/or parsing the request, and there is no guarantee that there were no more "standard" POST fields following the file data, so PHP will throw all of it away, in case one of the potentially missing fields is crucial and the fact that it's missing will cause your application to make an unintended change to your server. – DaveRandom Nov 01 '11 at 18:04

4 Answers4

2

If an array can only fit 50 indexes and you push 100, would you expect the other 50 to remain somewhere?

The same applies to this setting. Though there may be SOME POST data that can fit in the maximum size, having a piece of the expected whole would cause far more problems than having none at all. Right?

It's far easier to detect an EMPTY post than it is to detect an incomplete one.

I believe this is their rationale.

Jason Palmer
  • 731
  • 4
  • 17
1

To answer part of your second question, with .NET, if the POST is larger than maxRequestLength (part of the .NET configuration), but smaller than maxAllowedContentLength(part of the IIS configuration) you can create a custom HTTP module to get at the portion of the POST that came through.

Without the custom HTTP module, it'll just throw an exception. And you want maxRequestLength to be the limiting factor, otherwise IIS will deal with it instead of .NET.

Community
  • 1
  • 1
Kenny Linsky
  • 1,726
  • 3
  • 17
  • 41
0

I can't speak for the implementer, but the code is simpler that way. Since the superglobals are cooked, they would have to make decisions about how to handle partial posts, which would inevitably lead to confusion for many people. There are also the alternatives of:

$data = file_get_contents('php://input');

or looking at $HTTP_RAW_POST_DATA although afaik, neither of these work with multipart/form-data.

Kenny Linsky
  • 1,726
  • 3
  • 17
  • 41
gview
  • 14,876
  • 3
  • 46
  • 51
0

It's a really frustrating and bizarre facet of PHP's code. Some say it's quite sloppy design, but hey, it's a problem which can easily be avoided -- and, if anything, it's something which should only reaffirm how important UI and data transfer design is.

With forms which are bound to exceed ini settings (file uploads, lots of text, etc.) I always upload things asyncronously to a tmp directory which is wiped daily. If the form completes (now stripped of a lot of its data), the files are transferred into permanent locations.

You can always check if things have gone wrong by starting your form processing method with something like:

if(empty($_POST))
{
  // show error to user
}
hohner
  • 11,498
  • 8
  • 49
  • 84