Thursday, October 25, 2007

Upload progress bar with PHP5, APC and jQuery

Yesterday I wrote a little tutorial (Italian language, sorry) that explain how to create an info panel while a file is uploaded.

Here You can view final result:


While this is the entire archive with everything You need to test by Yourself my code:
APCQuery

To test them You need PHP 5.2 or greater and APC enabled.
Please verify that rfc is enabled too:
extension=php_apc.dll
apc.rfc1867 = On


If You test them locally please remember to try form using big files (from 40Mb to 200M for fast PCs) changing php.ini upload_max_filesize and post_max_size directives (I suppose 200M is enough).

If someone is interested about an English version of tutorial I'll try to find time to translate them.

32 Comments:

Blogger marc.lang said...

Great work dude, just a small question: In my case, index.html is a php-file with some custom content which should be forwarded to upload.php. There are some routines which I have to keep. This wont work if the page stays at index.php.

Is it possible to "really" go to upload.php with all the data from index (instead of let the index-page open and load upload.php in the background)?

07 November, 2007 16:51  
Blogger Andrea Giammarchi said...

marc if You try to upload one file without Ajax You can see that the page, in your case upload.php, will be visible only when upload has been finished (I didn't try forcing flush and manageing upload after first one, the page) so You could change JavaScript function and redirect user at upload finished using a different redirect page on action url for JS disabled browsers too.

07 November, 2007 17:03  
Blogger marc.lang said...

well thats what I've tried, altering the Javascript but I didn't find the correct lines so far. Could you tell me what I have to alter, which lines I have to change so the upload bar is still visible and workin?

08 November, 2007 10:07  
Blogger Andrea Giammarchi said...

uhm ... it seems You need n English version of my tutorial? I hope I'll find time to write them soon :-)

08 November, 2007 10:59  
Blogger marc.lang said...

Well, I've been workin on this for quite some time now and I'm really tryin to get this finished soon. I've already read your tutorial (translated by google) but I didnt find the part which would solve my problem but I have to admit that I'm not that experienced with Java yet. What I've done so far is to change this one:
"form name="fileupload" enctype="multipart/form-data" action="APCQuery.class.php?redirect=upload.php" method="POST"
Now the redirect is set but you won't get redirected if Java is enabled right? What I would like is to redirect in any case, even if java is enabled :/

08 November, 2007 11:04  
Blogger Andrea Giammarchi said...

Marc ... anyone talked about Java, We're talking about JavaScript so I suppose You're not so skilled with this language ...

However this was a tutorial, not a perfect/portable library and You need to change both client and server code to adapt them correctly.

For example:
APCQuery.class.php?redirect=upload.php
should be changed into
APCQuery.class.php?redirect=upload.php&nojavascript=page2.php
and at this point You could manage form action to change behaviour (both client and server code) with compatible/not compatible browsers.

08 November, 2007 11:12  
Blogger marc.lang said...

Idd, thats what I've said before, I'm not that familiar with JS. However I think you got me on the wrong foot. What I was tryin to explain was the following:

- Javascript enabled = stay on index.html, upload bar shown

- Javascript disabled = redirect to the page I want, no upload bar shown

What would be the best:
-JS enabled/disabled = upload bar shown AND redirect

08 November, 2007 11:37  
Blogger Andrea Giammarchi said...

marc ... again, if You don't have JavaScript You'll never see next page before You haven't send entire file.

So, without JavaScript You'll wait the end of uploaded file and only after them You'll see next page.

Do You need this is different? Change header("Location: "); redirect for disabled browsers.

Do You need to view them before upload is not completed or instantly when user click on upload button? No way man! ... and this is PHP ... not my tutorial problem ...

08 November, 2007 12:09  
Blogger marc.lang said...

Hm, I fully understand and know that but this was never my point.

EVERYONE who visits my upload-page has javascript ENABLED. Your progress bar works fine, status and so on is just perfect.

All I wanted to do is to redirect the user AFTER the upload is complete (with js enabled).

So my question was, how do I redirect the user after he has uploaded a file when Javascript is ON? Because I only get redirected when I turn JS off.

08 November, 2007 13:37  
Blogger Andrea Giammarchi said...

Ok marc, I didn't probably understand You.

To redirect JS enabled browsers Yous hould add them inside onload function, exactely after this line

apcquery.css("visibility", "hidden");

You should put your redirect:
location.href = "pageAfterUpload.html";

08 November, 2007 14:14  
Blogger marc.lang said...

Perfect dude, thats exactly what I was looking for. Thanks, that one made my day. Now I'll have a look how to send the var's from index.php to upload.php but I think I will get that sooner or later. Thanks again mate. Great!

08 November, 2007 14:26  
Blogger עידו said...

Hi
you have an syntax error.
its working fine with your example of the demo but whene im using it in drupla its does not fined the file input in the form.
filter("[type=file]") when you need to do filter("[@type=file")

i hope i helped someone...

30 November, 2007 23:23  
Blogger Andrea Giammarchi said...

Oops, thank You :-)

01 December, 2007 10:43  
Blogger Labanux said...

I've download APCQuery, and installed it on my local server.

But it didn't work as it should..

I browse the file, then click the upload button. Then the upload progress showed up. But the upload progress information never updated.

It just show Total, sent, and rate : 0 bytes. Meanwhile the progress bar never showed up.

And afther clicked the upload button, the upload button itself disabled forever..

Any suggestion?

NB: I've installed APC, and it works. Cause i've tried using other uploader script, and it works well.

02 December, 2007 04:22  
Blogger Andrea Giammarchi said...

labanux You should tell me wich version of PHP You have in your server.

My example simply works for everyone but not for You so I think the problem should be the PHP version or your specific configuration, isn't it?

02 December, 2007 18:33  
Blogger Labanux said...

As I said before, i've tried other Ajax Uploader with APC - script. And it works well..

These are software version that I use : Apache/2.2.4 (Unix) DAV/2 mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.1 mod_apreq2-20051231/2.5.7 mod_perl/2.0.2 Perl/v5.8.7

The APC version is 3.0.15

*I'm using Debian Linux, btw..

Should I made any changes to your script before I can use it?

NB: The script that I use is located here http://progphp.com/progress.php (if i'm not wrong it was made by Rasmus itself).

Any clue?

03 December, 2007 17:54  
Anonymous thuyetti said...

Hello and thank you very much for this tutorial, it works perfectly for me. But for now i'd like to pass the value of an input field (text input) from the upload form page to the upload.php. Àny idea ?

12 December, 2007 17:46  
Anonymous Anonymous said...

Italian language, sorry...

SORRY?!?!?! What do u mean... Sorry...

:-(

Davide

30 January, 2008 18:07  
Anonymous Anonymous said...

I've been searching for around an hour looking for a nice PHP/JavaScript solution that shows your upload progress, then I stumbled upon your site... Very well done! I think if you commented your code a little more, it may help people who need to alter the standard mechanism of the code.

I may need some more help when I implement this into a site I'm working on, but again - you've done a good job!

26 February, 2008 04:37  
Anonymous Anonymous said...

I've found a particularly problematic line of code in the APCQuery.class.php file. I was getting the same problem as labanux, where nothing was showing up in the Upload section, and the upload didn't do anything.

On line 45 of APCQuery.class.php, you have:

if($_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'] === str_replace('\\', '/', __FILE__)){

I found that my Windows server's DOCUMENT_ROOT variable was different - it had '\' characters instead of '/', which was making the 'if' statement fail, and therefore do nothing! I replaced mine to this:

if(str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']) === str_replace('\\', '/', __FILE__)){

I think this might even be safe to remove (or replaced with another check).

This took me literally hours to find, so I hope this helps!

17 March, 2008 13:06  
Blogger Andrea Giammarchi said...

Cheers! To be honest, I did not think about that kind of different configuration ... and I cannot understand the reason but anyway, your solution is really welcome ;)

Kind Regards

17 March, 2008 14:15  
Anonymous Spyer said...

Hey,, i've got to say, you wrote one hell of a script.. very nice..

but i'm having this problem.. i'm not so good in Java.. so your help is highly appreciated :)

//-------------->
Webpage Script Errors

User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0;)
Timestamp: Sat, 22 Mar 2008 18:46:17 UTC

0.
Message: 'length' is null or not an object
Line: 85
Char: 3
Code: 0
URI: http://localhost/upss/

Apache/2.2.6 (Win32) DAV/2 mod_ssl/2.2.6 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5
//<----------

Help please

22 March, 2008 20:12  
Blogger Lorenzo said...

Your code looks nice, without testing anything yet. However, I'm not familiar with APC but as far as I can see you are only using it to once? apc_fetch() from the class file. Now I was wondering, to avoid the hassle of installing APC, wouldn't it work fine by saving the id in session $_SESSION?

Thanks.

13 May, 2008 21:05  
Anonymous Anonymous said...

I've been using this script for several months now, with great success. THANKS SO MUCH FOR IT! Now I'm trying to move my scripts over to a new machine, and I'm having the same problem Labenux is having. When the upload button is pressed, the upload button grays out, the progress bar box is displayed, but everything remains 0, no file is uploaded, and the page stops loading ("done").

It still works great on my old machine:
- Ubuntu 7.10 box, Apache/2.2.3 (Ubuntu) mod_python/3.2.10 Python/2.5.1 PHP/5.2.1 mod_ruby/1.2.6 Ruby/1.8.5(2006-08-25) mod_perl/2.0.2 Perl/v5.8.8

My new machine is running:
- Ubuntu 8.04, Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.1 with Suhosin-Patch mod_ruby/1.2.6 Ruby/1.8.6(2007-09-24) mod_ssl/2.2.8 OpenSSL/0.9.8g

I've been working on this for more than a day now, and I can't readily find the difference, besides the newer versions. I have exhaustively compared the php.ini and apache2.conf files. Between the two servers, they are practically identical (a few comments differ. :/)

Any thoughts?
- Thanks!

07 June, 2008 17:57  
Anonymous laschmoove said...

Hi Andrea, thank your for your excellent script. I hope I may ask you for another advice: I need to write some data to a database after uploading the file, but since the upload.php is called internally it does not allow me to echo a message in case of success or failure. How would you handle that problem? Thanks, B.

06 July, 2008 16:35  
Anonymous huglester said...

Hello. and thanks for such nice tools.
But in my environment it doesn't work, I see get requests like:
GET http://aaa.com/APCQuery/APCQuery.class.php?APC_PK[]=1.7955122241208508 (31ms)jquery-1.2.1.js (line 2387)
GET http://aaa.com/APCQuery/APCQuery.class.php?APC_PK[]=1.7955122241208508 (16ms)jquery-1.2.1.js (line 2387)
GET http://aaa.com/APCQuery/APCQuery.class.php?APC_PK[]=1.7955122241208508 (31ms)jquery-1.2.1.js (line 2387)
GET

it seems like file is beeing uploaded, but lastly I get:

data has no properties
[Break on this error] while(i < data.length){

(those debuggin messages i got from Firebug)

apc.php shows that APC is running, and apc.rfc1867 is On .
I think the system can't handle tha ppaths. Because even while uploading , I can't find temporary files in php temp directory... strange

thanks in advance

15 August, 2008 09:39  
Anonymous huglester@gmail.com said...

heya.
anonymous with Ubuntu 8.04 , have you found the sollution?

I tried to recompile php without SUHOSINS patch - same problem as without removing it.

I see GET queries like:
http://192.168.1.107/apc/APCQuery.class.php?APC_PK[]=1.7168347417735283

seems the file is being uploaded.
I tried to find where it places temp files, even while uplaoding I can't see temporary file.
Could anyone try to help me, finding it ?

and later, after file is uplaoded, i see this error:

data has no properties
[Break on this error] while(i < data.length){

anyone could be of any help?

17 August, 2008 16:47  
Anonymous huglester said...

After my tests, it seems:

this progress bar cannot work with:
suhosin's patch.

and if php works as fastcgi - it cannot work too.

So if you are under (ubuntu 8.04) where php comes with suhosin already - you must rebuild witout suhosin.

I can help you with that. just email me at
huglester@gmail.com

good luck!

20 August, 2008 07:27  
Blogger Joao Pedro said...

the progress bar is not working fine for me ...
i have apc extension installed and correct discribed on phpinfo.
can someone help me ?
thanks.

23 September, 2008 16:05  
Blogger mariuz said...

I have tested and indeed it doesn't work
with jaunty and that patch suhosin

12 February, 2009 00:00  
Blogger Be a Javascript RockStar said...

awesome!

04 March, 2009 17:41  
Anonymous Arnold Roa said...

There is some error with the code in windows.

$_SERVER['DOCUMENT_ROOT'] = c:/test/
$_SERVER['PHP_SELF'] = /admin/bla.php

you concatenates the 2 vars:
c:/test//admin/bla.php
and compares to ___file___:
c:/test/admin/bla.php

you see the double //?

the correction is:

if(str_replace('//', '/', $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']) === str_replace('\\', '/', __FILE__)){

20 April, 2009 03:20  

Post a Comment

Links to this post:

Create a Link

<< Home