Handling HTML forms in PHP seems like straightforward task. Usually it is – until you meet some edge cases. On of such cases is handling when user tries to upload too large file using the form.
PHP has setting for file upload limitations. Parameter is called upload_max_filesize. By default it is set to 2 MB which means PHP would not allow files larger than 2MB to be handled by form.
How do you handle such case? It is quite simple: PHP would return uploaded file size (in $_FILES) as zero. All you have to do is check for file size and if it is equal to zero, file was to large and PHP did not allow upload.
But, that is not all.
PHP has other limitation, called post_max_size. By default it is also quite small and can cause lot of headache to find out if it is causing issue.
If uploaded file is larger than upload_max_filesize but less than post_max_size, PHP would behave as already descried: you would get file size as zero. but, if size of uploaded file is larger even than post_max_size things get complicated.
In that case, PHP just resets (unsets) both $_POST and $_GET. Both variables became unset. That is all. No other indicator that something is wrong.
Problem starts because in most cases you expect $_POST to be set as indicator that form is posted. It it is reset, your code treats it as nothing is posted and proceeds as that is the case. Your user is confused because after he posts from, form gets cleared and page shows as he just arrived to it. when user reports problem to you, you are also confused. Even if you debug code. All you can see is that even if form is properly posted, your code does not get content in $_POST. It is unlikely you will ever think that cause is in uploaded file size.
How to prevent this?
Instead of expecting $_POST to have content as indicator that form is posted, check if $_SERVER[[‘REQUEST_METHOD’]]) contains value of ‘POST’. That is sure method to establish if user actually posted a form. Then if $_POST is empty that is sure sign that something went wrong, most likely uploaded file is larger than post_max_size.