【问题标题】:Getting ftp_put progress获取 ftp_put 进度
【发布时间】:2010-05-21 20:50:21
【问题描述】:

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

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

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

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

这对我来说似乎非常低效。有没有更好的办法?

【问题讨论】:

  • Ajax 似乎总是很棘手,因为每次请求时(不确定)都需要新的 ftp 连接,不是吗?

标签: php ajax ftp


【解决方案1】:

使用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);

【讨论】:

    【解决方案2】:

    如果其他机器上的 ftp 服务器支持REST 命令(从某个点重新开始上传),则有一种肮脏的方式来实现:

    1. 创建临时文件
    2. 从您要上传的文件中将 X 个字节放入此文件
    3. 上传临时文件
    4. 将状态写入另一个文件(或会话,但不确定它是否会起作用)
    5. 将另一个 X 字节附加到临时文件
    6. 从 X 字节开始上传临时文件
    7. 将状态写入文件
    8. 重复 5-7 直到上传整个文件
    9. 删除临时和状态文件。

    示例代码:

    $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;
    

    【讨论】:

    • 或者你可以flush()进度
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多