/    Sign up×
Community /Pin to ProfileBookmark

AJAX/PHP Upload

Ok, I’ll ask this question in this forum because it does pertain slightly to PHP and nobody is answering me in the Javascript forum.

I am trying to come up with a method to upload a file and when the upload is finished, the filename shows up with a delete button next to it where the file input element was…..this is all without a page refresh, hence the AJAX.

So I know that I need to send my upload command through a hidden IFRAME. But the things is, I do not know how to tell when the file has completed the upload, thus I do not know when to call an AJAX function to display that the file was uploaded…..

So what I am looking for is one of two things:
Either someone can give me a better idea on how to do an AJAX upload with PHP
OR
Someone can give me an idea on how to tell when my upload is finished in the IFRAME (through Javascript perhaps?)

to post a comment
PHP

19 Comments(s)

Copy linkTweet thisAlerts:
@MatMelNov 22.2006 — Wouldn't it be possible to run a JavaScript function by the onLoad event of the site that is loaded in the invisible iframe?

Then this function could show the success-message in the parent frame...
Copy linkTweet thisAlerts:
@bokehNov 22.2006 — this is all without a page refresh[/QUOTE]Why?
Copy linkTweet thisAlerts:
@aj_nscauthorNov 22.2006 — bokeh, because this is the way I would like to have my forms set up. It's for the administration area of a site and its actually for attaching files to blog entries, this would allow me to attach a file and work on the blog entry at the same time, which I find most appealing. I know it's dead easy to do on separate pages with separate forms but I'm more interested in doing it this way.

MatMel, I was originally thinking that but this IFRAME is also loaded before any form is submitted to it.
Copy linkTweet thisAlerts:
@MatMelNov 22.2006 — 
MatMel, I was originally thinking that but this IFRAME is also loaded before any form is submitted to it.[/QUOTE]

But you could add the onLoad event using PHP, when a form is submitted to it!
Copy linkTweet thisAlerts:
@aj_nscauthorNov 22.2006 — Yeah I could, and I've thought about many things like that using both PHP and Javascript, I was just hoping that somebody could provide me a less complex solution on how to upload something and have a link to it display using some combination of AJAX and PHP
Copy linkTweet thisAlerts:
@sitehatcheryNov 22.2006 — The question is whether or not you can upload a file without refreshing? If so, then it should be easy to run a check in Javascript to see whether or not the file that you just uploaded now exists in the upload directory. If so, then display the button. But, you can't get to this point anyway if it is not possible to upload a file without refreshing. This should be in Javascript, but it's a very interesting concept (though I don't know if it is of any value). Out of pure intrest, does anyone know if it is possible in any programming language to upload a file without refreshing?
Copy linkTweet thisAlerts:
@aj_nscauthorNov 22.2006 — You can do that with a hidden IFRAME, sitehatchery. The question is, though, how do I know when to run this Javascript (i.e. when do I know that the upload is finished?)

Also, I'm not familiar with anything in Javascript that will tell me if a file exists on a server..
Copy linkTweet thisAlerts:
@hastxNov 22.2006 — Out of pure intrest, does anyone know if it is possible in any programming language to upload a file without refreshing?[/QUOTE]

I'm not familiar with AJAX, but my experience with trying to do similar things with JS is that the javascript will execute prior to the php fully having a chance to process...it seems that if you wish to do it that way you will have to get fairly complex with setting timeouts, etc.
Copy linkTweet thisAlerts:
@sitehatcheryNov 22.2006 — If you wish to use an Iframe, then if you can use Javascript to get the iframe to trigger an event in the parent browser window, then you've got a good start.
Copy linkTweet thisAlerts:
@bokehNov 22.2006 — how do I know when to run this Javascript[/QUOTE]Here's how I'd do it.

Main Page & Iframe page. Put the file field and upload script in the in the Iframe.[code=html]<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
</form>[/code]
No submit button though. Put the submit button on the main page and and have it fire a Javascript event. Both pages will activate a PHP session. When the submit button is pressed hide the iframe and button. Display an image that says loading (or something else to reassure the client). Submit the form in the Iframe that was hidden. The uploaded file can be saved to a session variable rather than to file. Poll the server every few seconds to see if that variable exists. Once that returns positive the upload is complete. Close the iframe. Display whatever flag you want to represent the action is completed on the main page.
Copy linkTweet thisAlerts:
@aj_nscauthorNov 22.2006 — Finally, I've got a good suggestion here. A question though, about the 'polling the server' part..

how do I do this?
Copy linkTweet thisAlerts:
@bokehNov 22.2006 — Do you know how to send an AJAX request? The PHP bit is simple. You are just checking a boolean. Does the variable exist or not.
Copy linkTweet thisAlerts:
@aj_nscauthorNov 23.2006 — Ok, I wasn't sure if the variable would exist anyways, just whether it contained the file data or not. I'll try it.
Copy linkTweet thisAlerts:
@hyperliskNov 23.2006 — Or, you could just have PHP print out some JavaScript to update the main window...

[code=php]
<?php

/* Blah blah.. uploading code here... */

echo <<<END
<script language="JavaScript">
onload = function(){
var del = document.createElement('input');
del.type = 'button';
del.value = 'Delete '.$filename;
del.onclick = function(){
window.frames['myiframe'].src = 'delete_file.php?file=$filename';
/* Not sure if this part will work... uncomment it to try it...
this.form.removeChild(this);
*/
}
window.top.uploadForm.removeChild(window.top.uploadForm.file);
window.top.uploadForm.appendChild(del);
}
</script>
END;
?>
[/code]

Of course, you would want to have delete_file.php do some session check and other stuff or else it would be a major security hole...
Copy linkTweet thisAlerts:
@bokehNov 23.2006 — Just to clarify uploading a file with the XMLHttpRequestObject is impossible. Mozilla needs elevated priveliges in [I]about:config[/I] and in IE it's completely impossible so the Iframe method seems like the only one.
Copy linkTweet thisAlerts:
@bokehNov 23.2006 — Ok! Here's the code to do it. No AJAX requests involved. For simplicity I've used alerts where you would be writing to the page. Nevertheless this is a full working demo.[code=php]<?php

session_start();

if(isset($_GET['upload']))
{
if(empty($_FILES))
{
?>

<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
</form>

<?php
}
else
{
if($_FILES['upload']['error'] == 0)
{
# file contents will be store in variable below for later use
$_SESSION['file'] = file_get_contents($_FILES['upload']['tmp_name']);
echo '<p>success</p><p>'.($_SESSION['filename'] = $_FILES['upload']['name']).'</p>';
}
else
{
$errors = array(1 => 'php.ini max file size exceeded',
2 => 'html form max file size exceeded',
3 => 'file upload was only partial',
4 => 'no file was attached');

echo '<p>upload error</p><p>'.$errors[$_FILES['upload']['error']].'</p>';
}
}
}
else
{
?>

<script type="text/javascript">
function upload(caller)
{
document.getElementsByTagName('iframe')[0].width = 0
FORM = IFRAME.document.getElementsByTagName('form')[0]
caller.style.display = 'none'
FORM.submit()
// insert a loading image or message in the page at this point
CYCLE = setInterval("TestUpload()", 200)
setTimeout("clearInterval(CYCLE)", 30000) // just in case something went wrong
}

var CYCLE = null

function TestUpload()
{
if(Ps = IFRAME.document.getElementsByTagName('p'))
{
clearInterval(CYCLE)
if(Ps[0].firstChild.nodeValue == 'upload error')
{
alert('No file was uploaded due to the following: '+Ps[1].firstChild.nodeValue)
}
else if(Ps[0].firstChild.nodeValue == 'success')
{
alert(Ps[1].firstChild.nodeValue + ' was up loaded successfully and stored in $_SESSION["file"]. Now do the rest of the javascript to make the delete button, etc.')
}
}
}
</script>

<h2>This is here to show there is no refresh!</h2>
<iframe style="display:block" name="IFRAME" src="?upload" width="400" height="40" scrolling="no" frameborder="0"></iframe>
<button onclick="upload(this)">upload it</button>

<?php
}

?>[/code]
Copy linkTweet thisAlerts:
@aj_nscauthorNov 23.2006 — I knew that this was an interesting feature. I thank you very much for taking the time to write this bokeh. I'm going to give it a shot and see if I can do the right stuff with it. Thanks again.
Copy linkTweet thisAlerts:
@aj_nscauthorNov 23.2006 — Hopefully you'll come back to this thread again bokeh, but if you don't I'll send you a private message:

How do I turn the session variable with the file data into a file on the server?
Copy linkTweet thisAlerts:
@bokehNov 23.2006 — How do I turn the session variable with the file data into a file on the server?[/QUOTE]Well right now you don't want it to be a file. No point saving it while the user has the option to delete it. Once they submit the form with the blog entry it is simply a matter of saving it to file at that point. Depending on your PHP version that would either use file_put_contents or a combination of fopen and fwrite.
×

Success!

Help @aj_nsc spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.6,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...