2011-03-29 121 views
2

我有一个应用程序,它有一个输入=文件文件上传并移动到另一台服务器

现在我需要上传到我的服务器,然后移动文件到其他服务器。我该如何避免超时?

此外,任何好的建议对Ajax上传。谢谢。

+0

尝试闪光jquery-flash上​​传。 http://www.uploadify.com/ – 2011-03-29 05:26:24

+0

@experimentX:谢谢 – 2011-03-29 06:23:52

+0

不,这只是上传。如何移动到另一台服务器,我仍然不知道,也许你应该设置一些接口或API或.. – 2011-03-29 06:27:25

回答

5

闪存者:毫无疑问,SWFUploadUploadify或(基于后者)。

文件传输:使用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,那么你很安全。顺便说一句,在正确的条件下(输出缓冲关闭和隐式输出开启),您可以向用户显示当前的远程传输进度。我已经完成了,这并不难。你只需要一个隐藏的iframe,它发送进度请求来更新父窗口。 它的工作方式类似于AJAX,但使用iframe代替XHR(因为XHR作为批量返回,不像iframe那样以块的形式返回)。

如果有兴趣,我可以帮你出这一点,只问。

EDIT3:动态远程上传例子/解释:

为了使事情变得很短,我会假设你的文件已经被用户上传到服务器上,而不是目标远程服务器。我还会假设用户在上传文件后登陆到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! 
+0

我对你如何实现远程传输进度感兴趣。我一定非常想知道你是怎么做的以及如何做到的。请解释。 – 2011-04-01 04:27:22

+0

@ I-M-JM - 好的,我会在上面更新我的帖子。 – Christian 2011-04-01 06:25:36

+0

从手册中:“最长执行时间,以秒为单位,如果设置为零,则不施加时间限制。” http://php.net/manual/en/function.set-time-limit.php – eisberg 2011-04-01 07:10:55

0

使用即SCP或rsync将文件传输到另一个服务器。每隔几分钟做一次cron作业,而不是从你的php脚本 - 这将防止任何超时发生,如果服务器到服务器传输时间过长。

相关问题