我有一个应用程序,它有一个 input = file
现在我需要上传到我的服务器,然后将文件移动到其他服务器。我怎样才能避免超时?
此外,对ajax上传者的任何好建议。感谢。
答案 0 :(得分:5)
Flash上传器:毫无疑问,SWFUpload或Uploadify(基于后者)。
文件传输:使用PHP CURL进行HTTP POST表单传输(http://www.php.net/manual/en/function.curl-setopt.php参见第二个示例)。
在进行转移之前,请执行以下操作:
set_time_limit(-1); // PHP won't timeout
ignore_user_abort(true); // PHP won't quit if the user aborts
编辑:我没有看到为什么你需要CRON作业的正当理由,除非有问题的文件在某个时间发生变化(这是同步的真正定义)。另一方面,如果您想要的只是将文件复制到远程服务器,那么您就没有理由不能使用普通的PHP。
另外,您应该注意的一件事是文件大小。如果文件大小小于20mb,那么你就是安全的。
编辑2:顺便说一句,在正确的条件下,(输出缓冲关闭和隐式输出打开),您可以向用户显示当前的远程传输进度。我做完了,真的不难。您只需要一个隐藏的iframe,它发送进度请求以更新父窗口。 它有点像AJAX,但使用iframe代替XHR(因为XHR作为批量返回,而不是像iframe那样以块的形式返回)。
如果有兴趣,我可以帮您解决这个问题,请问。
编辑3:动态远程上传示例/说明:
简而言之,我假设您的文件已经由用户上传到服务器,但不是目标远程服务器。我还假设用户在上传文件后登陆handle.php
。
handle.php
看起来像是:
// This current script is only cosmetic - though you might want to
// handle the user upload here (as I did)
$name = 'userfile'; // name of uploaded file (input box) YOU MUST CHANGE THIS
$new_name = time().'.'.pathinfo($_FILES[$name]['name'],PATHINFO_EXTESION); // the (temporary) filename
move_uploaded_file($_FILES[$name]['tmp_name'],'uploads/'.$new_name);
$url = 'remote.php?file='.$new_name; ?>
<iframe src="<?php echo $url; ?>" width="1" height="1" frameborder="0" scrolling="no"></iframe>
<div id="progress">0%</div>
<script type="text/javascript">
function progress(percent){
document.getElementById('progress').innerHTML='%'+percent;
}
</script>
到目前为止看起来不难,不是吗?
下一部分有点复杂。文件remote.php
看起来像是:
set_time_limit(0); // PHP won't timeout
// if you want the user to be able to cancel the upload, simply comment out the following line
ignore_user_abort(true); // PHP won't quit if the user aborts
// to make this system work, we need to tweak output buffering
while(ob_get_level())ob_end_clean(); // remove all buffers
ob_implicit_flush(true); // ensures everything we output is sent to browser directly
function progress($percent){
// since we're in an iframe, we need "parent" to be able to call the js
// function "progress" which we defined in the other file.
echo '<script type="text/javascript">parent.progress('.$percent.');</script>';
}
function curlPostFile($url,$file=null,$onprogress=null){
curl_setopt($ch,CURLOPT_URL,$url);
if(substr($url,0,8)=='https://'){
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
if($onprogress){
curl_setopt($ch,CURLOPT_NOPROGRESS,false);
curl_setopt($ch,CURLOPT_PROGRESSFUNCTION,$onprogress);
}
curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt($ch,CURLOPT_USERAGENT,K2FUAGENT);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_MAXREDIRS,50);
if($file){
$fh=fopen($file);
curl_setopt($ch,CURLOPT_INFILE,$fh);
curl_setopt($ch,CURLOPT_INFILESIZE,filesize($file));
}
$data=curl_exec($ch);
curl_close($ch);
fclose($fh);
return $data;
}
$file = 'uploads/'.basename($_REQUEST['file']);
function onprogress($download_size,$downloaded,$upload_size,$uploaded){
progress($uploaded/$upload_size*100); // call our progress function
}
curlPostFile('http://someremoteserver.com/handle-uplaods.php',$file,'onprogress');
progress(100); // finished!
答案 1 :(得分:0)
使用ie scp或rsync将文件传输到另一台服务器。每隔几分钟使用一个cron作业,而不是从你的php脚本 - 这将防止在服务器到服务器传输花费太长时间时发生任何超时。