MAX_FILE_SIZE in PHP - what's the point?
Solution 1:
After failed attempt to find any authoritative information about MAX_FILE_INFO i've decided to resort to drastic measures - and peeked at PHP's holy source.
I scanned entire PHP source recursively using grep:
grep -ri MAX_FILE_SIZE .
The only place that mentioned this variable was (excluding tests folder) - rfc1867.c file. Completely expectable since rfc1867 standard deals with file uploads.
Related C code:
......
if (!strcasecmp(param, "MAX_FILE_SIZE")) {
max_file_size = atol(value);
}
......
......
if (PG(upload_max_filesize) > 0 && (total_bytes+blen) > PG(upload_max_filesize)) {
cancel_upload = UPLOAD_ERROR_A;
} else if (max_file_size && ((total_bytes+blen) > max_file_size)) {
cancel_upload = UPLOAD_ERROR_B;
} else if
....
So - here's short explanation of above code:
1) first we get the value of MAX_FILE_SIZE into max_file_size variable.
2) Then we check if max_file_size value exists and if the sum of already accepted bytes (total_bytes) + the size of bytes in the buffer(blen) exceeds max_file_size.
3) If 2 is true - at this point we cancel upload with some error code that's been set by this constant: UPLOAD_ERROR_B
BUT - as you can see - right before checking max_file_size variable - PHP performs EXACTLY THE SAME CHECK for upload_max_filesize variable!!! So - there we have it.
Conclusion: IMHO - op is right - there is 0 point in including MAX_FILE_SIZE into your forms! Simply set upload_max_filesize in your php.ini file or dynamically via ini_set().
Solution 2:
At the moment there are no browsers that actually care about the MAX_FILE_SIZE directive so it is pretty pointless. I suppose it does give you more granular control over max sizes on upload (as the poster above stated) rather than going with php.ini's, but personally I just ignore it, and you probably should too. It will certainly not stop a user uploading a larger than required file - the manual is fairly misleading in this regard.
Solution 3:
Until we find browsers that support it, there's no point on the client side.
However, on the server side, MAX_FILE_SIZE
does affect the values you get from $_FILES['your_file']
.
Assuming the browser's request actually made it through post_max_size
, usually this is what PHP gives:
array(5) {
["name"]=> string(11) "my_upload.dll"
["type"]=> string(24) "application/x-msdownload"
["tmp_name"]=> string(26) "C:\WINDOWS\Temp\php86A.tmp"
["error"]=> int(0) // UPLOAD_ERR_OK
["size"]=> int(238592)
}
But if uploaded file size exceeds MAX_FILE_SIZE
, you'd see:
array(5) {
["name"]=> string(11) "my_upload.dll"
["type"]=> string(0) ""
["tmp_name"]=> string(0) ""
["error"]=> int(2) // UPLOAD_ERR_FORM_SIZE
["size"]=> int(0)
}
And the part on "MAX_FILE_SIZE
must precede the file input field" is not a joke. It actually works because PHP will interpret the browser's POST
request payload sequentially:
<input name=F1 type=file>
<input name=F2 type=file>
F1 and F2 will not be affected by MAX_FILE_SIZE
<input name=MAX_FILE_SIZE value=1024 type=hidden>
<input name=F3 type=file>
<input name=F4 type=file>
F3 and F4 will have MAX_FILE_SIZE = 1024 bytes
<input name=MAX_FILE_SIZE value=0 type=hidden>
<input name=F5 type=file>
<input name=F6 type=file>
F5 and F6 will have MAX_FILE_SIZE = 0 (infinite)
<input name=MAX_FILE_SIZE value=1 type=hidden>
<input name=F7 type=file>
<input name=F8 type=file>
F7 and F8 will have MAX_FILE_SIZE = 1 byte
Also note that PHP interprets MAX_FILE_SIZE
case insensitively, so maX_fILe_sIZE
and Max_File_SIZE
would work too.