2011-03-29 60 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腳本 - 這將防止任何超時發生,如果服務器到服務器傳輸時間過長。

相關問題