Is it possible to obtain file upload information in php

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Is it possible to obtain file upload information in php

Post by Fourtet »

At the moment I am simply displaying a loading message using plain javascript while the upload runs and then redirecting to a upload complete page. (Better than just freezing the screen I suppose)

Now I have heard a lot about XmlHttpRequest and AJAX and after seeing megaupload.com (http://www.megaupload.com/) which has a very useful progress bar I wondered how they accomplished this. After some looking at their source and doing some research I believe that they must of patched their PHP installation with this (http://pdoru.from.ro/)

Now, what about people on shared servers who don't have the ability to apply patches? Any advice would be appreciated.

If it's not possible, could anyone suggest a way for me to improve my routine? For example perhaps going to an intermediary "uploading" page to ensure the user doesn't click away from the task. I've seen something like that on (http://www.yousendit.com) which works quite well, how do you think this was done?

Thanks.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

I usually just have a div layer that completely covers the form that the file is uploaded from, when they hit the upload button that div layer becomes visible, I can then write "uploading..." to the div layer, since the div layer covers the whole form they cant mess around or accidentally re-submit the form (well I guess they could by using keyboard shortcuts, unless you disable all the form elements). This method has been fine for all my needs, another thing I did on one site was just disable every form element, and change all the text to light grey, a message appeared underneath the form that read "uploading, please wait...", it looked very 'professional' the way the whole page kind of grayed itself out, and it prevented the user from re-submiting the form. I'd be interested about that progress bar and if you can get it to work on a shared host. Sounds like a cool feature.

Edit:
hmm an idea, what if you used RPC (remote procedure calls) to dynamically write to that div layer, you could at the very least obtain the bytes uploaded, maybe through activeX or something else you could get the total file size and go from there
Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Post by Fourtet »

The problem is with RPC calls is they won't handle file uploads. It's supposedly a security risk so client side scripts can't copy files to the server. There are ways around it I think like with that PHP patch and the ruby on rails patch.

I'm still looking for anything that shows different.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I can see a cleverly written hidden iframe who's source is mapped to this file. Then, using XMLHTTP, the contents of that are sent, albeit a tiny bit slower than standard uploading, you would get a pretty accurate picture of progress is you sent packets of your own create so as to not bog the browser too much...
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Perhaps continue displaying your javascript message (perhaps with something moving so they know something's going on.

Something like:

Code: Select all

<?
echo "Uploading file";
sleep(1);
echo " . ";
sleep(1);
echo " . ";
sleep(1);
echo " . ";
sleep(1);

// this would display "Uploading file . . . "

// refresh page to keep the message 'moving'
?>
<script language="text/javascript">
<!--
setTimeOut(resetMessage(),5000);  // 5 seconds

function resetMessage
{
   document.reload();
}
//-->
</script>
Of course, this would have to be in perhaps a small popup window, or a tiny iframe. You could probably do it on the same page using strictly javascript.

Then if a person tries to navigate away from the page, or close the browser during upload, send them a prompt telling them to click OK or Cancel, informing them that clicking ok will interrupt their upload.

Something along those lines...
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Post by Fourtet »

Thanks Scrotaye, that's more or less what I'm doing right now except I'm also hiding div's from a javascript function called at document.onload.

Feyd, I've seen a few people mention the use of hidden iframes. I don't quite understand the logic behind this method. I've also not been able to dig up any examples of this in use, not sure if you know of anything?

So let me get this straight so I can have a crack at it, you have a hidden iframe with the source as the page it is actually on, then what? You use xml http request to update the iframe? I think it's the sending of the actual file I'm stuck mentally at, I don't see how it's possible with xmlhttprequest.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

the iframe idea would likely work like this:

dynamically change the "src" attribute to the local file to be uploaded.
wait for the browser to finish loading it into memory (using the onload event, maybe)
Once it's loaded you can 1) do a length on the document string to find the size, 2) break it into chunks so you can send packets of information in an XMLHTTP loop pushing 1K or something at a time.


'course, if the browser is smart enough to disallow Javascript to load a local file, then you're screwed. :) You'd need to switch to a Java/ActiveX/Perl/Flash/whatever thing then...
Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Post by Fourtet »

Logic sounds a bit iffy to me mate. :)

I'm still a bit miffed on the whole procedure, is it something like:

- Wait for form submit
- Change iframe src to name of submitted file
(This is where I'm lost, how will it "load the file to memory"
- Then use xmlhttp to send the data to the server
(Also lost here, does it just fill the iframe with binary data from the uploaded file? And how should you handle this data server side?)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

if it works, yes, the browser will fill the iframe with the binary data; and you'll transport the upload via xmlhttp where the server will have to piece it all together again.
Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Post by Fourtet »

I tell you now that won't work, I thought you'd done it before and maybe I was wrong.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

I'm not sure about feyds method of loading a local file into an iframe, if something like that worked a potential attacker could just upload a users hard drive through javascript without their knowledge, right?

The method of RPC which I meant was do something like:

User hits upload button which calls a javascript method to make an RPC call through an iframe, the iframe outputs javascript which uses calls the parent's javascript (the original form) to toggle a div layer's visibility to on, and writes "uploading, 0 bytes uploaded". [javascript also calls document.forms[0].submit()]

The iframe previously mentioned would not only call that parent method, but it would output javascript code to refresh itself at a specific interval, say every 500 milliseconds, so every 500 milliseconds the iframe calls a parent method with something like

Code: Select all

setbytesuploaded(2346);
, of course the php script that is outputting to that iframe would just go something like

Code: Select all

<script type="text/javascript" language="javascript">
     setbytesuploaded(<?=filesize($tempfile)?>);
</script>
You would have to find a way to make sure you get the right tempfile, as to not display the bytes uploaded to another user's file.

Edit:
If you don't understand the RPC via iframe concept go to http://developer.apple.com/internet/web ... frame.html so we can keep this thread on the topic of file uploading and not RPC

Edit: Edit: One more thing, while all this fancy 'smancy stuff probably impresses 95% of your users, the other 5% has javascript disabled.. so always have a way for the user to upload their file without upgrading their browser :wink:

accessibility over aesthetics
Last edited by josh on Sat Sep 03, 2005 11:22 am, edited 1 time in total.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Sounds like that method would be OK, but the progress bar would not be accurate, and the accuracy would depend greatly on the amount of tempfiles one had.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

It wouldn't be a progress bar, it would simply display the bytes uploaded, you'd have to take other means to get the TOTAL file size, which would be required to get a percentage. The only flaw in my method would be stat'ing the correct tempfile, and I'm sure there's a way I'm just too lazy to think of it right now.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

my idea is possible, btw. XPCOM in Firefox and ActiveX in IE can access, read, and write to the local filesystem. XPCOM is deactivated by default for web stuff, but enabled for things like XUL. So, using an extension for Firefox users and an ActiveX script for IE would offer it.
Fourtet
Forum Commoner
Posts: 29
Joined: Fri Sep 02, 2005 5:55 pm

Post by Fourtet »

Thanks Jsh, I'm trying to implement this now and I've got my RPC working with an iframe finally. (XMLHttpRequest is so much easier imo :)) I'm trying to work out how to get the file information though once submitted to the iframe. I'm a bit stuck on that. :cry:
Post Reply