How to gracefully handle files that exceed PHP's `post_max_size`?
From the documentation :
If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty. This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e. <form action="edit.php?processed=1">, and then checking if $_GET['processed'] is set.
So unfortunately, it doesn't look like PHP sends an error. And since it sends am empty $_POST array, that is why your script is going back to the blank form - it doesn't think it is a POST. (Quite a poor design decision IMHO)
This commenter also has an interesting idea.
It seems that a more elegant way is comparison between post_max_size and $_SERVER['CONTENT_LENGTH']. Please note that the latter includes not only size of uploaded file plus post data but also multipart sequences.
there is a way to catch / handle files exceeding max post size, this is my preferred on, as it tells the end user what has happened and who is at fault ;)
if (empty($_FILES) && empty($_POST) &&
isset($_SERVER['REQUEST_METHOD']) &&
strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
//catch file overload error...
$postMax = ini_get('post_max_size'); //grab the size limits...
echo "<p style=\"color: #F00;\">\nPlease note files larger than {$postMax} will result in this error!<br>Please be advised this is not a limitation in the CMS, This is a limitation of the hosting server.<br>For various reasons they limit the max size of uploaded files, if you have access to the php ini file you can fix this by changing the post_max_size setting.<br> If you can't then please ask your host to increase the size limits, or use the FTP uploaded form</p>"; // echo out error and solutions...
addForm(); //bounce back to the just filled out form.
}
else {
// continue on with processing of the page...
}
We got the problem for SOAP requests where a check for emptiness of $_POST and $_FILES doesn't work, because they are also empty on valid requests.
Therefore we implemented a check, comparing CONTENT_LENGTH and post_max_size. The thrown Exception is later on transformed into a XML-SOAP-FAULT by our registered exception handler.
private function checkPostSizeExceeded() {
$maxPostSize = $this->iniGetBytes('post_max_size');
if ($_SERVER['CONTENT_LENGTH'] > $maxPostSize) {
throw new Exception(
sprintf('Max post size exceeded! Got %s bytes, but limit is %s bytes.',
$_SERVER['CONTENT_LENGTH'],
$maxPostSize
)
);
}
}
private function iniGetBytes($val)
{
$val = trim(ini_get($val));
if ($val != '') {
$last = strtolower(
$val{strlen($val) - 1}
);
} else {
$last = '';
}
switch ($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
// fall through
case 'm':
$val *= 1024;
// fall through
case 'k':
$val *= 1024;
// fall through
}
return $val;
}