Forum Moderators: coopster
I tried 2 different aproaches on my site regarding upload of files:
(note: these are just rudimentary examples to show you what I mean, in the final version these would include checking for file, size etc...)
PHP only:
<?php
if (isset($_POST['Submit'])) {
$path= "upload/".$HTTP_POST_FILES['ufile']['name'];
if($ufile !=none)
{
if(copy($HTTP_POST_FILES['ufile']['tmp_name'], $path))
{
echo "Successful<BR/>";
}
else
{
echo "Error";
}
}
}
?>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td><strong>Single File Upload </strong></td>
</tr>
<tr>
<td>Select file
<input name="ufile" type="file" id="ufile" size="50" /></td>
</tr>
<tr>
<td align="center"><input type="submit" name="Submit" value="Upload" /></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
PHP with FTP function (I guess):
<?php
if (isset($_POST['Submit'])) {
if (!empty($_FILES['upload']['name'])) {
$ch = curl_init();
$localfile = $_FILES['upload']['tmp_name'];
$fp = fopen($localfile, 'r');
curl_setopt($ch, CURLOPT_URL, 'ftp://user:pass@ftp.mysite.com/www/upload/'.$_FILES['upload']['name']);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);
$error_no = curl_errno($ch);
curl_close ($ch);
if ($error_no == 0) {
$error = 'File uploaded succesfully.';
} else {
$error = 'File upload error.';
}
} else {
$error = 'Please select a file.';
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
<div>
<label for="upload">Select file</label>
<input name="upload" type="file" />
<input type="submit" name="Submit" value="Upload" />
</div>
</form>
Both results are exactly the same, the speed and progress. I monitor upload via small freeware up.
What advantages might one method have over the other?
As in my case both ways produce terrible results - very slow with lots of pauses during the upload :(
This is for a video sharing site.
I have these values (loacal and master) set in my php.ini:
post_max_size = 900M
upload_max_filesize = 990M
max_execution_time = 30
max_input_time = 60
memory_limit = 64M
Everything runs fine if I upload a file that is under 100M, otherwise my browser throws an error after just a few seconds.
Example error from firefox:
Connection Interrupted
The connection to the server was reset while the page was loading.
The network link was interrupted while negotiating a connection. Please try again.
Any clues? thanks.
"Request Entity Too Large
The requested resource
/mysite/upload.php
does not allow request data with GET requests, or the amount of data provided in the request exceeds the capacity limit.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request."
Hmm... strange, why does it mention the GET request? Naturally my form is set to: method="post"
Other browsers were not that helpful in diagnostics, this is from Safari:
"Safari can’t open the page “http://www.mysite.com/upload.php”. The error is: “unknown error” (kCFErrorDomainWinSock:10053)"
Why do I keep reading on how it is much more advantageous solution?
You are probably reading these in context of getting around the default 2MB limit for upload. The problem with using FTP in a PHP script is that both the client (who's sending) and server must have an FTP program, it's an ftp-to-ftp solution and really won't "work" for the average web user using a browser. But I see you are tweaking your PHP limits to compensate . . .
I have these values (loacal and master) set in my php.ini:
post_max_size = 900M
upload_max_filesize = 990M
max_execution_time = 30
max_input_time = 60
memory_limit = 64M
If these were for image uploads I'd have other comments. But since it's for video, one thing you need to consider: for a, say, 100 MB video upload on a "decent" connection, how long do you think that might take to upload? I am absolutely sure it would take more that the 30 second execution time and 60 second input time you have there.
Even if you correct this, there is always the possibility the user's browser will time out long before the upload completes. IF you're going to take on such huge files, you need to come up with a solution that responds to the browser in a reasonable amount of time while running the time-consuming process in the background. fork() is the usual approach; you start a forked process, allow the child of the process to do the time consuming task, and once started the parent returns a response to the browser (see YouTube: "your video is being processed . . . ")
Memory limit *should* be fine, unless you are resizing huge images using the GD toolkit.
A caveat, you don't need to tweak your global php.ini, these exact same directives can be placed in the domain for per-directory access to limit "where" these huge numbers are applied. You also don't need to restart the server/php to allow these to take effect.
You are right about "max_execution_time", it does take much more then 30 seconds indeed :)
My connection is average at best, but during my testings (and I did many, lol) I didn't occur any timeouts or similar problems.
Test with 100MB video file:
- total uploading time - cca 1hour and 20 minutes
- average speed - cca 19-22 kb per second
- small pauses do occur at random, sometimes 5 minutes in between (I credit this to my ISP provider)
- total "stop" may occur, out of some 15 100MB tests I did in the last two days, I experienced it only once. But for assistance I've built a small "restart" button so user can instantly start the upload process again if something happens.
I believe these rare interruptions are unavoidable using the browser as an upload tool, because I experienced it many times when uploading large files to Youtube.
So everything seems to be fine now, except when the file is over 100 MB limit.
As I've said before, when choosing a file >100MB browser throws out an error almost immediately.
I was certain that the problem lies in "post_max_size" which was set to 100MB and was even more certain that the problem will go away once my ISP changes this value.
As I instructed them, they changed it to 990M,
Change is confirmed as I can see the new value when doing the "phpinfo()" to display my ini file, but the problem stayed.
Now, I'm really not that knowledgeable when it comes to ini files, actually I know very little about them and how they work.
But - is it somehow possible that these new "post_max_size" values have not taken effect? Does the server need to be restarted?
Again, I have no idea what it means to restart a server, sorry, I'm just plain coder :)
ut - is it somehow possible that these new "post_max_size" values have not taken effect?
Pull a phpinfo() on your domain, it will tell you.
Does the server need to be restarted?
For an .ini change, the server software needs to be restarted, yes, via command line or a control panel, but if you use an .htaccess file, no, it doesn't. The advantage with an .htaccess file is it only applies to the directory it's in. So if you specify a 900 MB post_max_size in your root directory, it won't apply to other areas of your site, which can be a security net in some cases.
i've had good success with megaupload in the past (for uploading >100mb dj mixes) - [sourceforge.net...]
But still no luck, whenever I add a file that is over 100MB, it uploads for 20 seconds and stops with the "The connection to the server was reset while the page was loading."
We tried the "set_time_limit(0);" among other option, nothing really works.
Do you have any other ideas/experiences? I'm willing to hear them all : )
My memory limit set today by my host provider is 128MB, coincidence or?
Does this mean that PHP holds all in memory or?
Ugh, I'm totally confused here guys..
But if it was a PHP thing, then why would this code also fail:
(as you this is only HTML)
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1">
Select file
<input name="ufile" type="file" id="ufile" size="50" /></td>
<input type="submit" name="Submit" value="Upload" />
</form>
Can it be something that is set in apache server? Totally beyond my knowledge, but do leave a comment if you have ANY ideas : /
I tested further to discover on what *exact* size I get an error, and guess what?
- 127 MB file : works FINE
- 129 MB file : FAILSMy memory limit set today by my host provider is 128MB, coincidence or?
Well, you'd previously said you set your memory limit to 990MB, maybe 128 is all your current host is allocating.
Maybe you need to upgrade your service to deal with these kind of file sizes.
it uploads for 20 seconds and stops with the "The connection to the server was reset while the page was loading."
Did you change max_execution_time and max_input_time? Did you verify these with phpinfo()?
I wouldn't take any of these approaches. What if your user is on a slower connection, how would you guess whether or not X MB will be fully uploaded before it times out?
As mentioned, you really need to look at fork() and initiate the upload as a background process. What you can do is
- fork the process. This provides a process id to the parent process. So let's say you do
if $pid = fork() { //return response to browser }
else {
// child upload process
}
If $pid exists, you can create a "monitor" you'd poll every five seconds or so using meta-refresh:
if ($pid) {
// check progress of process $pid
// you can check the file size of this file in this check
// if it keeps increasing, it's uploading.
}
else {
// $pid has ceased to exist
// Verify and get file size
// if file size is same as uploaded size
// (you'll have to manually check)
// file uploaded, otherwise it failed
}
This will allow it to run in the background, and not suck up all your memory. It's one way to do it without having the browser give up the ghost.