A "reliable" progress bar, which seems to be your goal, will always require some sort of server and client support. In its most general and portable instance, PHP will see only the completed upload and you'll get no progress bar, but only the filled $_FILES
structure.
On some platforms the information can be garnered from the system itself. For example under Linux/Apache you can inspect what temporary files Apache has opened in the /proc
pseudo-filesystem, where available; so you need to put in the requisites "Linux, Apache, php5_module, /proc".
You can use a dedicated POST endpoint that does not terminate on the Web server, but on a specially crafted uploader process (I worked on a Perl script doing this years ago; I recall it used POE, and the architecture):
POST (from browser) ==> (server, proxying) ==> UPLOADER
The uploader immediately echoes a crafted GET to the server, activating
a PHP "pre-upload" page, and then might call a progress GET URL periodically
to update the upload status. When completed, it would issue a pseudo POST
to PHP "almost" as if it came from the client, sending $_POST['_FILES']
instead of $_FILES.
The $_SESSION
solution is a good compromise but relies on the server not doing buffering.
A better and more "modern" solution would be to leverage the chunked upload AJAX trick and get resumable uploads, reliable progress and large file support all in one nifty package. See for example this other answer. Now you get wider server support but the solution won't work on some older browsers.
You could offer the user the choice between old-style FILE upload, Flash uploader (which bypasses all problems as it doesn't rely on the browser but on Flash code), Java FTP upload control (same thing, but sometimes with some protocol and firewall issues since it doesn't use HTTP as the container web page does), and AJAX HTML5 chunking, possibly based on browser capabilities.
I.e., a user with IE6 would see a form saying
SORRY!
Your browser does not support large file uploads and progress bar.
To send a file of no more than XXX meg,
[ ] [Choose file...] [ >> BEGIN UPLOAD >>> ]