I have a PHP form for uploading files and it works fine and displays an error message if something went wrong. This is all good.
The problem is when I test with a really big file, it just refreshes the page as if I hadn't sent a file at all, and none of the $_POST variables from the form are even sent to the server.
I want to display an error to the user, letting them know that the file is too big. However, I can't do this.
Does anyone know what is happening?
Check your PHP ini file, which governs how large a file PHP will allow to be uploaded. These variables are important:
max upload filesize (upload_max_filesize)
max post data size (post_max_size)
memory limit (memory_limit)
Any uploads outside these bounds will be ignored or errored-out, depending on your settings.
This section in the docs has the best summary: http://ca3.php.net/manual/en/features.file-upload.common-pitfalls.php
EDIT: Also note that most browsers won't send uploads over 2GB in size. This link is outdated, but gives an idea: http://www.motobit.com/help/scptutl/pa98.htm. Anyone have a better source of info on this?
There are also limits that can be imposed by the server, such as Apache: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody
To truly see what's going on, you should probably check your webserver logs, check the browser upload limit (if you're using firefox), and try seeing if print_r($_FILES) generates any useful error numbers. If all else fails, try the net traffic monitor in firebug. The key is to determine if the request is even going to the server, and if it is what the request (including headers) looks like. Once you've gotten that far in the chain, then you can go back and see how PHP is handling the upload.
Your $_POST is most likely empty because the upload exceeded the post_max_size directive:
From PHP's directives page:
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.
you can not know the size of the file that is being uploaded, until it gets fully uploaded. so if you want to determine the file size, and then show an error for large files, first you must have the file uploaded, then check the file size. inorder to have a large file uploaded, you should set 2 settings in your php configuration file, php.ini.
open it up and search for "upload_max_filesize" and set the value to maximum value you want. then you must set the maximum value for POST parameters, because uploaded files are recieved via HTTP POST method. find "post_max_size" and set it to a large value to.
apart form the options as the former users answered:
max upload filesize (upload_max_filesize)
max post data size (post_max_size)
memory limit (memory_limit)
there is also one, when the file is very large, or the line is busy, there need to much time to execute this operation, which will hit to ceil of the script execution limit.
max_execution_time
I would implement a simple script that does regular ajax calls to know how much of the upload has been done. You can then implement some sort of progress bar. There are a couple of examples on the net:
http://martinjansen.com/2007/04/28/file-upload-progress-bars-with-php/
max upload filesize (upload_max_filesize)
max post data size (post_max_size)
are the directives you need to set. I have tested it with multiple OS, browsers etc and these are the only two thing you need be worried about.
Related
Sorry if it is trivial or obvious, but I could not find the answer by googling it.
From where does the size value in $_FILES['name'] array come from? Could you trust the value of it ($_FILES['name']['size']) or should you still check it using the filesize() function?
In other words, is it necessary to check actual file size by filesize function to notice if it is properly uploaded?
If the file is uploaded correctly and everything is fine, you can use the info provided by PHP superglobal $_FILES. Using filesize() adds small overhead since OS needs to inspect the file for the size. It's up to you, but checking PHP source on how it does all this indicates clearly that it correctly calculates the file size in the HTTP multipart request. Basically, you'd be doing the same job again if you were to filesize() the file.
The reason you can trust this directly from superglobal variable is the fact that multipart requests supply a boundary between which the data resides. By definition, it's not possible to obtain corrupt data if the protocol for extracting the data isn't followed. In other words, it means that browser sends a "delimiter" and PHP simply finds it and starts checking the text for data between that delimiter. To do this, it accurately allocates required memory and it can immediately cache the number allocated - and that number is the file size. If anything is wrong along the way, you will get errors. Therefore, if the file uploaded correctly, the information about the size is trusted.
PHP does seem to recalculate the size of the file after it is uploaded. Although the client does send a header specifying the content-length of the file, based on tests (with PHP 5.5) this header is simply ignored and, instead, the length is measured. Personally, I would always use filesize() to get the file size since you can be more confident about which measurement is being used, but it is ultimately up to you. Either way, $_FILES['file_name']['size'] appears to be a safe value to use.
You should rather check if the client-reported $_FILES['file_name']['size'] equals the value given by filesize(). A difference may indicate an error during transmission of the uploaded file.
I'm getting some variables with $_POST, mainly inputted by the user on a form.
To prevent huge values to be inserted in the form, I can check those variables and return an error to the user if they're to long.
However, I can't do that if the user input a REALLY long value because, in this case, the entire script crash before I can even refuse to process that variable. Is this a threat to the security of my server?
How can I fix this without increasing the default memory limit? Is it possible?
Restraining user input with a javascript could be an option, but the user may easily overcome that limit by disabling javascript.
You can limit the maximum size of a post body using the ini directive post_max_size. However its defaults to 8M. If it is unchanged it should be ok as the default memory_limit is 128M. (php 5.3)
But of course this depends on what you are about to do with the data and how much memory PHP will consume for this. In extreme speak, it would be even possible to create an example script that reaches the memory limit with a 1 byte input. So you'll have to find the proper value for your application.
From the documentation
Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. If memory limit is enabled by your configure script, memory_limit also affects file uploading. Generally speaking, memory_limit should be larger than post_max_size. When an integer is used, the value is measured in bytes. Shorthand notation, as described in this FAQ, may also be used. 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. , and then checking if $_GET['processed'] is set.
Do you have access to php.ini? You can set upload_max_filesize / post_max_size
See here for details: http://php.net/manual/en/ini.core.php#ini.sect.file-uploads
(p.s. setting maxlength in the HTML form is easily circumvented by a malicious user)
Divides the data on the client into parts and download in parts via Ajax, then save the downloaded part on the disc or in the database. Maybe this way?
I made a simple script that uploads file that are submitted through a simple html form,
It works fine with files that are smaller than 5 mega bytes.
When I upload larger files they start to screw things up..
I thought it might be that the execution time is too short, so I used this:
set_time_limit(500);
Sadly, it didn't make any difference.
In the form, I have a hidden input that helps me detect if the form was submitted
Next, I checked the apache error log and I found that that input was null,
So it seems like the long execution time loses the other values..
is there any simple solution for this? or shall I just change the way I detect if the form was submitted?
Thanks
Please check you php settings in php.ini for maximum post size with post_max_size = ?
I have that basic, well known multiple file upload form. Something like that...
<input type="file" multiple="multiple" name="something[]" />
Is there a way (preferable a hard coded option) to limit the number of files that user can select? By limit i mean strictly blocked, not just a warning if number is exceeded.
Thanks in advance. :)
You can implement a javascript solution to check the number of files that have been selected, which you can then use to forbid uploading to the server. There are really only going to be client-side solutions to this problem though, as there is really nothing stopping a user from posting these files to your php script anyway. You can specify a maximum upload size limit, but it isn't specific to the number of files that are being uploaded.
Your best bet is to implement some javascript checking, specifying a reasonable maximum upload size for your http server (or in PHP), and then ignoring any file uploaded if it exceeds your maximum count.
Read about the HTML5 File API here to restrict the count of selected files: http://dev.w3.org/2006/webapi/FileAPI/
Here is the php.ini docs which explain how to make a size limitation on uploads: http://php.net/manual/en/ini.core.php
As was suggested in the comments, check out: http://php.net/manual/en/ini.core.php#ini.max-file-uploads
we all know that in an array first element is stored in 0 th index, 2nd in 1st index......nth in (n-1)th index
now you cant take count($_FILES['something']) which will always return 5 since there are 5 keys in the array
now the question is what does $_FILES['something']['name'][0] contains? => name of first file uploaded
so check like
if(empty($_FILES['something']['name'][0]))
{
//checking whether a single file uploaded or not
//if enters here means no file uploaded
//so if you want you may put a check/validation here to make file
//upload a must in your website
}
if(isset($_FILES['something']['name'][5]))
{
//checking whether 6 files uploaded or not
//so here you can put a check/validation to restrict user from
//uploading more than 5 files
}
Pure Js alternatives that do that and much more:
FineUploader. Demo
bluimp's jQuery File Upload Plugin. Usage: jquery file upload restricting number of files
They are also available at https://cdnjs.com/
Some plugins seem to assist with this, such as: Uploadify (flash based). However I haven't used this one or others enough to know if they how restricting they can limit uploads.
More info on Uploadify Multiple Uploads.
I have a form where users can enter multiple images to upload along with a bunch of other information. It looks like there is some condition that is causing the last few images not to upload, for some cases. For example, testing the form when uploading about 5 images, they all upload fine. When there are more, somewhere between 10 and 20-some, and this number does vary, then the last few may not upload. I've printed out the $_FILES array, and the selected images don't appear at all. So it looks like they aren't even being sent.
These images are quite small, only about 10-40k. My upload_max_filesize is 2M, and post_max_size is 8M, so that can't be it. Not only that, but these same images still fail to upload when the previous ones in the form are not uploaded - if you leave the first 20 file inputs blank, and select something for the 21st, that image still doesn't upload. And this has been tested with multiple images, so there isn't something wrong with the image file. Note - there aren't exactly 21 file inputs - it's variable, the user can add more or delete some.
I've also tested multiple browsers, and multiple computers. The only thing is that this problem happens only on my production server and has never occurred on my development server, so that could be a clue. It's also always the inputs at the end of the form, sometimes the last one, sometimes several, depending upon the form inputs being tested.
Is there any inherent limit to the number of file inputs you can have in a single form? I haven't pinpointed an exact number that causes the issue.
http://www.php.net/manual/en/ini.core.php
max_file_uploads 20 PHP_INI_SYSTEM
Available since PHP 5.2.12.
Could be max_execution_time for the receiving function. I think the default is often 30 seconds, and perhaps a large upload is taking longer than that?
If your dev server is localhost, that could be quite speedy and not have surfaced the issue until a true remote server was used?