Uploading chunked files to s3 with php - php

I have a php script where I store a file uploaded by the user in a tmp folder and then move it to s3. I also check if the emails they entered are valid in the database. I am using chunking so that large files can get uploaded to the server quickly. My post_max_size is 8M, however I am only able to upload files that are very small.
For example, If I upload a 7M file, I get an alert I set which says the file size is too large. This alert is only supposed to show if file size is >8M. If I upload a 1 KB file, it uploads the file successfully. Am I doing something incorrectly? I'm fairly new to php so I'd appreciate the help!

I'm not sure how relevant this may be, but I noticed that you haven't specified anywhere that the type of the data is "multipart/form-data". I've always been under the impression that a file upload won't work correctly unless this is specified.
Also not related per se but I see you're using jQuery. I recommend moving away from that and using the native fetch API. It's a cleaner and more modern solution.

ini_get('post_max_size') can (and will) return human-friendly values. So you will end up comparing integer file size values with string values (8M in your case). And 9000 > '8M'...
UPDATE:
There is no need to explicitly use the PHP configuration values post_max_size or upload_max_filesize, because:
in case of exceeding the post_max_size value, the $_FILES array will be empty, plus a warning will be generated, e.g.:
Warning: POST Content-Length of 3414 bytes exceeds the limit of 2048 bytes in Unknown on line 0
in case of exceeding the upload_max_filesize value, the corresponding 'error' field(s) within the $_FILES array will contain the UPLOAD_ERR_INI_SIZE value, e.g:
array(1) { ["name"]=> array(5) { ["name"]=> string(12) "filename.ext" ["type"]=> string(0) "" ["tmp_name"]=> string(0) "" ["error"]=> int(1) ["size"]=> int(0) } }
All the above mean that if there's a non-empty $_FILES array available and the value of the error field is UPLOAD_ERR_OK, you can be sure that the upload was successful and configuration values were also respected.
In your case this translates to the condition if ($_FILES['file']['size'] <= ini_get('post_max_size')) ... not only incorrect (comparing integer file sizes (e.g. 9000) with possibly non-integer strings (e.g. '8M')), but also not needed at all.

Related

file() PHP function , what is the max upload size to not crash the server when the conversion of the file to array is happening?

I'm using file() function to turn for example a .txt file into an array and the work easy with it. What I want to know is if there is some sort of file size limit (which I'm sure is) when we convert a txt file into an array. What is this limit? Should I check the filesize before applying the file() function over it? I just don't want to crash the server when someone uploads a 1MB file and then this file to array convertion will create a big server crash.
When you put a file content or query result or ... into an array there will be no limit except the memory that is assigned to PHP processes in the php.ini file. For example:
memory_limit = 256M
Some part of this assigned memory is dedicated to the PHP itself and the rest can be used for loading content as you mentioned. As far as I know, there will be no crashes in loading file content into the array. For example, sometimes 20MB of query results are stored in an array so why converting a 1MB file into an array could be a problem?!

PHP file input number limited to 20

I have multiple file uploads but the $_FILES seems to be chunked after 20 inputs
var_dump($_FILES); //gives array(20){ ... } although there are more file inputs
This is the public php_info
Which parameter is responsible for this limit ?
As a workaround, I used some javascript:
<input id="input_fileXX" type="file" class="input_file">
----
$('.input_file').on('change',function(){
$(this).prop('name',$(this).prop('id'));
});
This allows to only send the inputs that have change. This is useful when you can't change php.ini.
http://www.php.net/manual/en/features.file-upload.multiple.php
Since PHP 5.2.12, the max_file_uploads configuration setting acts as a limit on the number of files that can be uploaded in one request. You will need to ensure that your form does not try to upload more files in one request than this limit.

empty $_POST and $_FILE variable when uploading large files

I was trying to upload a file which is 20MB in size. Now default form upload size is 8MB. When I upload such a file i get $_POST and $_FILE variables empty. Now I want to put a check on file size. If I get both these variables empty, how can I put such a check ?? Please give me suggestions
Barring any code errors, its most likely your 20MB exceeds your upload limit.
Change this permanently from your php.ini file.
Use
ini_set("upload_max_filesize", "30M");
to set your max upload size for that session only. And for POST
Use this
ini_set("post_max_size", "30M");
To check the sizes
echo ini_get("post_max_size") . "\n";
echo ini_get("upload_max_filesize");
No idea what you actually want. But you can probe the recieved content size using:
$_SERVER["CONTENT_LENGTH"]
This should tell how big the POST request body would have been. (The number might be higher than the actual received content, in case of an aborted upload.)
Checkout php://input, the allowed 8mb part of it should be there.
For example echo file_get_contents('php://input');
You can dynamically set your max file size for upload.
write down below statement in your upload function where you are trying to upload file.
this will enhance limit up to 50 MB
ini_set("upload_max_filesize", "50M");
If you want to check file variables, you can user alternative HTTP_POST_FILES
$theFileSize = $HTTP_POST_FILES['file']['size'];
Hope this may help you.
Thanks.
Use MAX_FILE_SIZE as a hidden input field, this will stop the user waiting if the file is larger than the limit and won't execute your code so the variables won't be empty...
The MAX_FILE_SIZE hidden field (measured in bytes) must precede the
file input field, and its value is the maximum filesize accepted by
PHP. This form element should always be used as it saves users the
trouble of waiting for a big file being transferred only to find that
it was too large and the transfer failed. Keep in mind: fooling this
setting on the browser side is quite easy, so never rely on files with
a greater size being blocked by this feature. It is merely a
convenience feature for users on the client side of the application.
The PHP settings (on the server side) for maximum-size, however,
cannot be fooled.
http://www.php.net/manual/en/features.file-upload.post-method.php

What exactly does it mean when $_FILES is empty?

I am working on a PHP upload script and when testing my error checks, I attempted to upload a 17MB TIFF file. When I do this the $_FILES array is empty. The script works fine for what I need it to do, which is to upload JPEG files. My solution is to test if $_FILES is empty or not before continuing with the upload script.
Can anybody explain why $_FILES is empty when a TIFF is attempted to be uploaded? Is my solution, to check if $_FILES is empty or not, an okay one?
Does this have something to do with settings in php.ini?
Just to clarify
I was checking that $_FILES was empty using the following:
if(empty($_FILES))
{
die('$_FILES is empty.');
}
Yes, upload_max_filesize controls max upload size, which the TIFF file most likely exceeded. The default is 2M. You can test with:
echo ini_get("upload_max_filesize");
EDIT: Actually, the exact cause is more likely post_max_size, which is always >= upload_max_filesize: "If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty."
You should check to see if $_FILES['file']['error'] is equal to 0. This indicates a "success".
If your files array is empty, it might be due to some other problem, like not including the enctype.
Try doing var_dump($_FILES) and viewing the contents...
EDIT: I know you can set the max filesize in the php.ini file, but I am not sure if that will give you an empty files array. I think you will just get an error.
As posted already, it's empty because if failed. Also check for a form element like this:
<input type="hidden" name="MAX_FILE_SIZE" value="-maxsizegoeshereinbytes-" />
To be extra sure (once you actually have an array - adding to the 'check the error key' post, btw) , you can also check the size
if( $_FILES['file']['size'] > 0 ) {
}

MAX_FILE_SIZE in PHP - what's the point?

I was trying to make a file upload form and checked the PHP documentation to refresh my memory on the subject. Here is a link to the relevant article. All of a sudden I noticed this message:
The MAX_FILE_SIZE hidden field (measured in bytes) must precede the file input field, and its value is the maximum filesize accepted by PHP. This form element should always be used as it saves users the trouble of waiting for a big file being transferred only to find that it was too large and the transfer failed. Keep in mind: fooling this setting on the browser side is quite easy, so never rely on files with a greater size being blocked by this feature. It is merely a convenience feature for users on the client side of the application. The PHP settings (on the server side) for maximum-size, however, cannot be fooled.
OK... Say what? First it tells that it must precede the file upload field. Then it tells us that it is merely for convenience. And besides - it's on client side anyway so anyone can mess with it. After googling around I also found information that there are no known browsers that support it.
WTF? Why is it said that it must precede the file upload field if it seems to be (for all intents and purposes) absolutely pointless? Should I bother putting it in my HTML at all?
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().
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.
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.
I believe the point is that conformant browsers would prevent form submission in the case where the user selected a file that was too large, which would save them having to perform at least a partial upload (which could take a while) of a file that was going to be rejected.
On the server side, PHP still checks and enforces the various limits set in PHP.ini, and will reference the fact that an upload was too large in the normal manner, i.e. an error code set in $_FILES. You might think of the field as an analogy to JavaScript validation - we might do a quick client-side check for the user's convenience, but we still do a proper server-side test and enforce it for all requests.
As others have stated, there don't appear to be any browsers that actually bother to perform this check, making it relatively useless.
What follows is me being wrong, please read the other answers which are better-informed, and accurate (AFAIK).
I think the point is exactly as it states:
This form element should always be
used as it saves users the trouble of
waiting for a big file being
transferred only to find that it was
too large and the transfer failed
Yes, it can be fooled, and so shouldn't be relied on to prevent larger files from being uploaded, but for non-malicious users if the uploaded file is bigger than the integer in this field, PHP disallows this upload and presents an error code in the $_FILES array (source - comments on php.net).
I use it to set file size limit when a particular application needs smaller files than the limit in php.ini. My php scripts check it, but it is set in the HTML form. Different forms have different file size limits. I am not sure if this has much to do with the intended use, but it makes it easier to reuse my scripts. It would be good if it could be checked at the browser level, but it's not the only reason it is useful.

Categories