You are not logged in.

#1 24 Apr 2008 2:05 pm

Butcher
Moderator
From: Norway
Registered: Jul 2006
Posts: 308

File uploading with a progress bar

Something repulses me about using CGI and PERL for showing progress bars on uploads, it simply isn't a good method in the perspective of needed technologies and infrastructure on the web-server. I've heard of AJAX and Javascript progress bars made in combination with PHP to upload the file, which is far better because you can have all the files in one folder, it does not require upgrading PHP, most methods used are old and will pre-installed on most webservers.

But can anyone here muster a decent way of doing it? I've gone through near 20 upload scripts now, all of them flawed, impractical and not functional, so I wanna make a simple script that uses PHP to upload a file and showing the status of the upload (textual and graphically based) with AJAX or Javascript.

Any suggestions on methods are very welcome.


http://bamboocommandos.com/butcher_img/butchersig7.jpg

Offline

 

#2 24 Apr 2008 6:15 pm

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: File uploading with a progress bar

the only thing that's going to give you an accurate progress meter is the thing that is transferring the file.  in the case of a web page, its the browser who's actually sending the file over the socket to the web server and IMO there should be something that could be hooked into by a client side script that would allow you to see the overall progress of the file being posted to the server.  but they don't.

the only progress bars I've seen are the stupid spinners that don't really give you a feel for how much has actually been transferred.  I've also seen various hacks but none of them are a true representation of a file upload.

Offline

 

#3 25 Apr 2008 4:27 pm

Butcher
Moderator
From: Norway
Registered: Jul 2006
Posts: 308

Re: File uploading with a progress bar

Well, I just want it to give me a decent idea of the progress. For example, if I upload a 200 MB file (I am the kind of person not likely to go through explaining how to use a FTP program if a simpler and user-friendly method can be made), I would like to be able to check the site tab every now and then and see how far it has come.

I'd think that calculating a somewhat close measure of how long it will take by figuring out some smart way to determine the seconds, like setting a unix timestamp right before transfering a few KB's and then setting a timestamp after the transfer finishes, then easily calculating the kbps. It won't be completely accurate of course, but it should give the user a slight idea, like if he is on a 5 MB line or a hand-carved ISDN router.

The tricky part really, is determining percentage of completion without reloading (so it has to be client-side) by checking total filesize towards remaining filesize.

A other alternative would be using the newly developed APC package for PHP, though it requires php.ini to be changed and is not very user-friendly when it comes to installing (I crashed Apache 3 times before it got stable, it crashes with Zend optimizer very easily). But the whole point of a successful script would be making it easy, so that people installing it don't need to change .ini's, apply cgi or generally change their webserver or computer.


http://bamboocommandos.com/butcher_img/butchersig7.jpg

Offline

 

#4 27 Apr 2008 4:00 am

Butcher
Moderator
From: Norway
Registered: Jul 2006
Posts: 308

Re: File uploading with a progress bar

After going through a bunch of tutorials, blogs and scripts, I decided that for the purpose of storing pictures, it is not efficient using a progress monitor. I think it could be quite useful for large file uploads through a browser, but right now I do not need that. So, here is the super-easy image upload script:

Code:

<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

$time_start = microtime_float();
?>
<?php
$con = mysql_connect("localhost","user","password") or die ('Could not connect to MySQL database due to: ' . mysql_error());
mysql_select_db("database", $con);

if (($_FILES["file"]["size"] < 20971520))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
$size = ($_FILES["file"]["size"] / 1024);
$size = round($size);
$filename = $_FILES["file"]["name"];
$fileloc = $_FILES["file"]["tmp_name"];
$filetype = $_FILES["file"]["type"];
echo "Filname: " . $filename . "<br />";
echo "Type: " . $filetype . "<br />";
echo "Size: " . $size . " Kb<br />";
echo "Stored in: " . $fileloc;
}
}
else
{
echo "Could not upload";
}
$image = chunk_split(base64_encode(file_get_contents($fileloc)));
$name = mysql_real_escape_string($_POST['name']);
mysql_query("INSERT INTO `image` VALUES ('', '$name', '$image', '$ip')"); 
mysql_close($con);
?>
<?php
$time_end = microtime_float();
$time = $time_end - $time_start;

echo '<br>Upload took: ' . $time . ' seconds';
?>

Saving the images in a database rather than in a folder, with a maximum load of 20 Mb per image. Saved me a lot of time on the scripting part as well, just need a simple:

Code:

<?php
$id = $_GET['id'];
$con = mysql_connect("localhost","user","password") or die ('Could not connect to MySQL database due to: ' . mysql_error());
mysql_select_db("database", $con);
header('Content-type: image/jpeg');
$result = mysql_query("SELECT * FROM image WHERE id = '$id'");
while($row = mysql_fetch_assoc($result))
{
$image = $row['image'];
echo base64_decode($image);
}
?>

To show it anywhere. As you see, I am using a simple microtime for showing how long it took to execute the script, but is this an accurate description of the actual loading time?


http://bamboocommandos.com/butcher_img/butchersig7.jpg

Offline

 

#5 28 Apr 2008 10:08 am

MadHatter
Administrator
From: Dallas TX
Registered: Jun 2006
Posts: 529
Website

Re: File uploading with a progress bar

microtime is expressed in microseconds, which are going to be too precise to express in seconds (the underlying data type will clip the value to 0 most likely).  you can try using milliseconds (1 microsecond = 0.001 milliseconds) instead.

other than that, it looks great.

Offline

 



© 2003 - 2019 NullFX
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License