I also developed upload status capability for my company that works very similarly to yours. I am currently working on integrating the changes I made into a patch for 4.3.2 for members of this list to evaluate (I originally made the upgrade to 4.1.2).
I see you came to the same conclusion I did, that the easiest way to pass information seemed to be through the use of temporary files. I was hoping that once I submitted my patch that someone on this list might have a better suggestion like direction on using shared memory or something. --David -----=+=----- David Enderson Programmer Digital IMS 402.437.0137 [EMAIL PROTECTED] > Hi, > > To make a long story short, I needed an upload progress > metter, so the users will something while their huge files > are uploaded to the server. I searched the net but only found > for ASP, so I wrote one. Unfortunatly PHP needs a little > patch to be willing to do this ... > > Here is how it works: > 1. apply patch to php and recompile php (and apache if > needed) 2. add something like this to http.conf > > #for php-upload-progress-bar > <Directory /www/htdocs/upload> > php_value upload_metter 1 > php_value upload_metter_dir "/tmp/uploadbar" > </Directory> > > - This will activate the progress metter for /upload > - And will tell it to write progress informations to /tmp/uploadbar > > 3. mkdir /tmp/uploadbar; chmod 777 /tmp/uploadbar > I have to say that 0777 and /tmp are not the best choises from a > security point of view. you should find a better place! > > 4. copy the demo scripts to /upload directory > 5. point your browser to the index.php script. upload some > files. enjoy! > > > Here is how it really works: > 1. index.php will generate and uniq ID for each upload. This > ID will be used to track the progress and report it. 2. a > special field named 'UPLOAD_METTER_ID' is used to store this > ID. make sure this field is BEFORE any 'file' fields. put it > at the begining of the form! 3. onSubmit()-ing the form a > small window will open where the progress.php will display > the actual progress bar. 4. php will check the value of > 'upload_metter' and 'upload_metter_dir' configuration options > and the presence and value of 'UPLOAD_METTER_ID' field 5. the > progress file is stored in the directory named by 'upload_metter_dir' > and the vlaue of UPLOAD_METTER_ID field is used as the > name of the file 6. progress information is updated once a > second by the php engine 7. script progress.php will use the > ID field which it receives as a parameter to locate the > associated progress-file and read progress information from > it. then generate the little proggress bar 8. the progress > bar will 'refresh' about once a second, depending on how fast > the network is going 9. when upload is completed, the > progress.php script will remove the progress file, and close > the pop-up window. > > > NOTE: there is a good chance that this progress files will > not be deleted from various reasons (client don't have JS > activated, or it closes the popup while data is still > uploaded, etc...), so there is a need to periodically cleanup > the directory of old files. > > > What the PATCH does: > - adding 2 new cinfiguration options to PHP: upload_metter > and upload_metter_dir > - in rfc1867.c: changes rfc1867_post_handler() to make some > calls to a newly defined function that will update the > progress metter: > update_progress_metter() > - in turn it calls update_progress_metter_file(), trying its > best not to update the file more than once a second. > > I have tested it with php-4.2.3 and 4.3.2. atch for php-4.3.2 > is attached. a patch for 4.2.3 is also available. basically > is the same thing. > > the rest of the files and a live demo can be found here: > http://pdoru.from.ro/ > > > Please let me know if you have any problems/suggestions :-) > > > Best regards, > Doru Petrescu > Senior Software Engineer > Astral Telecom Bucuresti > > > > > -------------------------------------------------------------- > --------------------- > diff -rubB orig/php-4.3.2/main/main.c php-4.3.2/main/main.c > --- orig/php-4.3.2/main/main.c Thu May 22 01:54:38 2003 > +++ php-4.3.2/main/main.c Thu Jun 5 22:58:46 2003 > @@ -345,7 +345,9 @@ > STD_PHP_INI_BOOLEAN("file_uploads", > "1", PHP_INI_SYSTEM, OnUpdateBool, > file_uploads, php_core_globals, > core_globals) > STD_PHP_INI_ENTRY("upload_max_filesize", "2M", > PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateInt, > upload_max_filesize, php_core_globals, > core_globals) > STD_PHP_INI_ENTRY("post_max_size", > "8M", PHP_INI_SYSTEM|PHP_INI_PERDIR, > OnUpdateInt, post_max_size, > sapi_globals_struct,sapi_globals) > - STD_PHP_INI_ENTRY("upload_tmp_dir", > NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, > upload_tmp_dir, php_core_globals, > core_globals) > + STD_PHP_INI_ENTRY("upload_tmp_dir", > NULL, PHP_INI_ALL, OnUpdateStringUnempty, > upload_tmp_dir, > php_core_globals, core_globals) > + STD_PHP_INI_ENTRY("upload_metter", > "0", PHP_INI_ALL, OnUpdateBool, > upload_metter, php_core_globals, > core_globals) > + STD_PHP_INI_ENTRY("upload_metter_dir", > NULL, PHP_INI_ALL, OnUpdateStringUnempty, > upload_metter_dir, php_core_globals, > core_globals) > > STD_PHP_INI_ENTRY("user_dir", > NULL, PHP_INI_SYSTEM, OnUpdateString, > user_dir, > php_core_globals, core_globals) > STD_PHP_INI_ENTRY("variables_order", NULL, > PHP_INI_ALL, OnUpdateStringUnempty, > variables_order, php_core_globals, core_globals) > diff -rubB orig/php-4.3.2/main/php_globals.h > php-4.3.2/main/php_globals.h > --- orig/php-4.3.2/main/php_globals.h Sun May 18 13:22:16 2003 > +++ php-4.3.2/main/php_globals.h Thu Jun 5 22:56:57 2003 > @@ -133,6 +133,8 @@ > zend_bool modules_activated; > > zend_bool file_uploads; > + zend_bool upload_metter; > + char * upload_metter_dir; > > zend_bool during_request_startup; > > diff -rubB orig/php-4.3.2/main/rfc1867.c php-4.3.2/main/rfc1867.c > --- orig/php-4.3.2/main/rfc1867.c Sat May 24 00:37:16 2003 > +++ php-4.3.2/main/rfc1867.c Thu Jun 5 22:59:45 2003 > @@ -676,6 +678,81 @@ > return out; > } > > +typedef struct _Xdata { > + int time_start; > + int time_last; > + int speed_average; > + int speed_last; > + int bytes_uploaded; > + int bytes_total; > + int files_uploaded; > + char progress[1024]; > +} Xdata; > + > +static void update_progress_metter_file(Xdata *X) > +{ > + int eta,s; > + FILE *F = VCWD_FOPEN(X->progress, "wb"); > + > + s = X->speed_average; if (s < 1) s=1; > + eta = (X->bytes_total - X->bytes_uploaded) / s; > + > + if (F) { > + fprintf(F, > "time_start=%d\ntime_last=%d\nspeed_average=%d\nspeed_last=%d\ > nbytes_uploaded=%d\nbytes_total=%d\nfiles_uploaded=%d\neta=%d\n", > + X->time_start, X->time_last, > X->speed_average, X->speed_last, X->bytes_uploaded, > X->bytes_total, X->files_uploaded, eta > + ); > + fclose(F); > + } > + > + sapi_module.sapi_error(E_NOTICE, "metter: read %d of %d", > +SG(read_post_bytes), SG(request_info).content_length ); } > + > +static void update_progress_metter(Xdata *X, int read, int total) { > + int d,dt,dtx; > + int bu; > + int sp; > + > + > + if (!X->time_start) { > + X->time_start = X->time_last = time(NULL); > + > + X->bytes_total = total; > + X->bytes_uploaded = read; > + > + X->speed_average = X->speed_last = X->bytes_uploaded; > + > + update_progress_metter_file(X); > + return; > + } > + > + dt = time(NULL) - X->time_last; > + d = read - X->bytes_uploaded; > + > + if (dt < 1) { > + if (read < total) > + return; // avoid divide by zero > + if (d < 1) > + return; > + dt = 1; > + } > + > + > + > + sp = d/dt; > + > + > + X->bytes_uploaded = read; > + X->time_last = time(NULL); > + > + dtx = X->time_last - X->time_start; if (dtx > < 1) dtx = 1; > + X->speed_average = X->bytes_uploaded / dtx; > + > + X->speed_last = sp; > + > + update_progress_metter_file(X); > +} > + > > /* > * The combined READER/HANDLER > @@ -693,6 +770,10 @@ > zval *array_ptr = (zval *) arg; > FILE *fp; > zend_llist header; > + Xdata X; > + int progress_metter=0; > + > + bzero(&X,sizeof(X)); > > if (SG(request_info).content_length > SG(post_max_size)) { > sapi_module.sapi_error(E_WARNING, "POST > Content-Length of %d bytes exceeds the limit of %d bytes", > SG(request_info).content_length, SG(post_max_size)); @@ > -753,6 +838,9 @@ > zend_llist_clean(&header); > > if (!multipart_buffer_headers(mbuff, &header > TSRMLS_CC)) { > + > + > + if (progress_metter) > update_progress_metter( &X, > +SG(read_post_bytes), SG(request_info).content_length ); > SAFE_RETURN; > } > > @@ -806,6 +894,35 @@ > max_file_size = atol(value); > } > > + > + > + if (!strcmp(param, > "UPLOAD_METTER_ID") && PG(upload_metter) && PG(upload_metter_dir)) { > + char *c,*v = estrdup(value); > + for (c=v;*c;c++) { > + if ( (*c >= '0' && *c <= '9') || > + (*c >= 'a' > && *c <= 'z') || > + (*c >= 'A' && *c <= 'Z') || > + *c == '.' || *c == '_' || > + *c == ',' || *c == '@' || > + *c == '-' || *c == '%') { > + }else{ > + *c=0; > + break; > + } > + } > + > + if (v && *v) { > + if (strlen(v) > 64) v[64]=0; > + progress_metter=1; > + snprintf(X.progress,1000, > "%s/%s", PG(upload_metter_dir), v); > + } > + efree(v); > + > + > + > + } > + > + > efree(param); > efree(value); > continue; > @@ -831,6 +948,9 @@ > SAFE_RETURN; > } > > + if (progress_metter) > update_progress_metter( &X, SG(read_post_bytes), > SG(request_info).content_length ); > + X.files_uploaded++; > + > if (!skip_upload) { > /* Handle file */ > fp = > php_open_temporary_file(PG(upload_tmp_dir), "php", > &temp_filename TSRMLS_CC); @@ -872,6 +992,10 @@ > } else { > total_bytes += wlen; > } > + > + > + > + if (progress_metter) > update_progress_metter( &X, > +SG(read_post_bytes), SG(request_info).content_length ); > } > } > fclose(fp); > @@ -1047,6 +1173,10 @@ > efree(param); > } > } > + > + > + > + if (progress_metter) update_progress_metter( &X, > SG(read_post_bytes), > +SG(request_info).content_length ); > > SAFE_RETURN; > } > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php