文件上传并移动到另一台服务器

时间:2011-03-29 05:23:46

标签: php

我有一个应用程序,它有一个 input = file

现在我需要上传到我的服务器,然后将文件移动到其他服务器。我怎样才能避免超时?

此外,对ajax上传者的任何好建议。感谢。

2 个答案:

答案 0 :(得分:5)

Flash上​​传器:毫无疑问,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,那么你就是安全的。

编辑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脚本 - 这将防止在服务器到服务器传输花费太长时间时发生任何超时。