获得ftp_put进度

时间:2010-05-21 20:50:22

标签: php ajax ftp

我在Web服务器上有一个php脚本,它通过ftp_put将文件上传到另一台远程服务器。

如何向用户显示当前的上传进度?

我见过的唯一类似系统是用户上传文件,ajax请求检查服务器上传文件的本地大小。

等效系统是对Web服务器的ajax请求,然后检查远程服务器上的文件大小并将该数据返回给用户的clientscript。

这对我来说似乎非常低效。还有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

可以使用FTP URL protocol wrappers轻松实现:

$url = "ftp://username:password@ftp.example.com/remote/dest/path/file.zip";
$local_path = "/local/source/path/file.zip";

$size = filesize($local_path) or die("Cannot retrieve size file");

$hout = fopen($url, "wb") or die("Cannot open destination file");
$hin = fopen($local_path, "rb") or die("Cannot open source file");

while (!feof($hin))
{
    $buf = fread($hin, 10240);
    fwrite($hout, $buf);
    echo "\r".intval(ftell($hin)/$size*100)."%";
}

echo "\n";

fclose($hin);
fclose($hout);

答案 1 :(得分:1)

如果其他机器上的ftp服务器支持REST命令(从某一点重新开始上传),那么实现此方法的方法很简单:

  1. 创建临时文件
  2. 将X字节从您要上传的文件中放入此文件
  3. 上传临时文件
  4. 将状态写入另一个文件(或会话,但不确定它是否可行)
  5. 将另外X个字节附加到临时文件
  6. 从X字节开始上传临时文件
  7. crite status to file
  8. 重复5-7直到整个文件上传
  9. 删除临时&状态文件。
  10. 示例代码:

    $fs = filesize('file.bin');
    define('FTP_CHUNK_SIZE', intval($fs * 0.1) ); // upload ~10% per iteration
    
    $ftp = ftp_connect('localhost') or die('Unable to connect to FTP server');
    ftp_login($ftp, 'login', 'pass') or die('FTP login failed');
    
    $localfile = fopen('file.bin','rb');
    
    $i = 0;
    while( $i < $fs )
    {
        $tmpfile = fopen('tmp_ftp_upload.bin','ab');
        fwrite($tmpfile, fread($localfile, FTP_CHUNK_SIZE));
        fclose($tmpfile);
    
        ftp_put($ftp, 'remote_file.bin', 'tmp_ftp_upload.bin', FTP_BINARY, $i);
        // Remember to put $i as last argument above
    
        $progress = (100 * round( ($i += FTP_CHUNK_SIZE)  / $fs, 2 ));
        file_put_contents('ftp_progress.txt', "Progress: {$progress}%");
    }
    fclose($localfile);
    unlink('ftp_progress.txt');
    unlink('tmp_ftp_upload.bin'); // delete when done
    

    用ajax检查文件:

    if(file_exists('ftp_progress.txt'))
        echo file_get_contents('ftp_progress.txt');
    else
        echo 'Progress: 0%';
    exit;