Moin,
JavaScript can´t do this either (well some sort of proprietary Microsoft-language might be able to do that).
The Problem is, that - from what I´ve seen using strace - the Apache process will read the entire file into memory, will save it to disk once it is uploaded completely and then load the PHP script and execute it.
So obviously you can´t get the progress from within the script that get´s the file, which would be pointless anyway: The browser doesn´t start to read the answer until the full request (including the file upload) is complete.
However, I think I found two workarounds, though I´ve not coded any of these yet:
1. If you can use CGI, you will want to submit the file upload into a CGI-application. (I think it won´t work with PHP in CGI-Mode or with perl´s use CGI; albeit I´ve not tried it).
This CGI-Application will get the Content-Length that the browser sent in it´s environment and has to read the complete Request-Body (which includes the form fields and the uploaded files) from stdin. So it knows the size of all files it will get, it knows how much data it has read so far and thus it can compute the percentage that is already uploaded. With some knowledge of HTTP or some time of experimenting it shouldn´t be too hard to figure out, how to process the request body.
You will need to use a frameset and some JavaScript in the upload form to start (with JS) a second request in a different frame than the one the upload is targeted at. This second request will then use your favorite form of Interprocess Communication to talk with the CGI-application that is receiving the file and will then be able to display a progress bar.
All in all, quite challenging, but not impossible.
- If you can´t use CGI-applications but only PHP as a server module, you´ve got a problem. As I said above the server will not give you any hint about how much it has already received. (You´d have to modify the servers source code or be root and peek around in the servers memory space to get that information. You don´t want to do that 🙂
Ok, so the server that is already there is not good for what you want -> You´ll have to write your own server ... in PHP. I did that, it´s not too hard. You will need socket(), bind(), listen() and accept_connect() (PHP 4.0.2 - 4.0.6) or socket_create(), socket_bind(), socket_listen() and socket_accept() (PHP 4.1) and a PHP version that has socket support compiled in.
You will then use onSubmit in Javascript to load your http-server-php-script into the frame that should display the progress bar. This script will open some high port and listen for a connection. It also has to send some javascript code, that will tell the browser to redirect the file upload to our newly created http-server.
It reads the request, will get the Content-Length and the uploaded files, thus it can print out the upload progress.
Once the request is complete, it should send a redirect to the browser that will bring the browser to a result page (this is because the port will close immediately after, and we won´t want the browser to reload that frame, or something like that), can process the request and do whatever you wish with the uploaded files and then close the port.
Have fun...
--
Henryk Plötz
Grüße aus Berlin