This post is archived and probably outdated.

Upload Progress in PHP trunk

2010-12-03 19:31:40

File uploads via HTTP are an annoyance. Web Browser know quite a lot but still the give little feedback to the users. Some a bit more, most close to no feedback. Now over the years this led to man unhappy users. Over the last year, with all these AJAX things, solutions emerged so that one can periodically poll the web server on a second connection for the status. For implementing this we have one architectural problem: PHP implements, for very good reasons, a shared nothing architecture. So one request from connection has no insight into another request/connection - but this is needed for the upload progress. Different people thought about this and implemented solutions. One of the first things was implemented in APC, another one by a special uploadprogress extension. They are nice and found quite some adoption but they have two problems. For one they are not fully native to PHP, so they have to be installed additionally, and the use a local storage to transport the status. APC uses the system's shared memory. upload_progress the filesystem (yes, file systems could be shared, I do know that). not very satisfying for having PHP as the language for solving the web problem.

The obvious solution, of course, would be to use PHP's session handling system for this. The PHP session system is an integral part of PHP and can be configured to use different storage handlers, like the local file system or memcache, which can be useful to share session data in a load-balanced cluster. Now there were some technical issues why this wasn't done at first ... but then Arnaud Le Blanc sat down and created a proper implementation of an upload progress storage handler which has been commit to PHP trunk.

Long story short: In the next version of PHP (5.4?) you will, mot likely, have an Upload Progress mechanism built-in.

Arnaud wrote a nice RFC explaining this functionality. So we configure our PHP to enable this feature, by making sure we have the default values:

session.upload_progress.enabled = 1 
session.upload_progress.prefix = upload_progress_
session.upload_progress.name = PHP_SESSION_UPLOAD_PROGRESS

And we are set to go. Then we obviously need an HTML file upload form:

<form action="upload.php" method="POST" enctype="multipart/form-data">
 <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="johannesupload" />
 <input type="file" name="file1" />
 <input type="file" name="file2" />
 <input type="submit" />
</form>

And we can upload a file. If the file is big enough (and the connection slow enough) we can then periodically poll the server and read and read data about the progress from the $_SESSION["upload_progress_johannesupload"] variable. The full contents is mentioned in the RFC, so I won't quote it here.

So far so good. But how to poll? Well, take the sample by Rasmus about the above mentioned APC-based solution and adopt it. I let this to the experienced reader as exercise :-)

Disclaimer: This article is describing features in not released software. Things may change without notice till it is release. Feel free to read other blog postings from my series of new features!

P.S. I still think the browser should give better feedback by itself. As should it offer better integration of HTTP-Auth, like a simple logout button ...