如何获得复制的进度

时间:2017-10-16 21:12:00

标签: php

我有这个代码可以复制文件,是否有可能获得复制的数量?

    <?php
$src = '../www/';
$dst = '../../backup/'; 

function recurse_copy($src,$dst) {
    $dir = opendir($src);
    @mkdir($dst);
    while(false !== ( $file = readdir($dir)) ) {
        if (( $file != '.' ) && ( $file != '..' )) {
            if ( is_dir($src . '/' . $file) ) {
                recurse_copy($src . '/' . $file,$dst . '/' . $file);
            }else {
                copy($src . '/' . $file,$dst . '/' . $file);
            }
        }
    }
    closedir($dir);
}
    recurse_copy($src,$dst);

}
?>

如果有可能通过ajax响应获得该数字。这意味着必须多次发送响应。但我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

您可以使用引用传递的第三个参数来跟踪复制的文件。

function recurse_copy($src, $dst, &$copied) {
    // recurse code
    $copied[] = [ 'src' => $src, 'dst' => $dst, 'file' => $file ];
    copy($src.'/'.$file, $dst.'/'.$file);
}
$copied = [];
recurse_copy($src, $dst, $copied);
print_r($copied);

当您将函数放在类中时,其他方式可能是闭包(赋值给变量的函数)和use语句或类属性。

修改

有关实时更新的进度,请参阅echoflush()以查看半实时复制的文件。无法在文件副本中取得进展。

答案 1 :(得分:0)

有两种方法:

  1. 了解您要复制的文件数量,以便显示%
  2. 不知道文件总数
  3. 在第一种情况下,您必须先获取完整的文件列表,然后再进行复制。根据目录树的大小和文件数量,它可能会增加一些开销,但它有其好处。你必须决定。

    在任何情况下,您都必须在函数中添加第三个参数:

    function recurse_copy($src, $dst, callable $progress_callback = function(){}) { ... }
    

    请记住,只有PHP 5.4以后才支持callable

    回调函数的签名是:

    function handle_progress($action, $data) { ... }
    

    然后你可以像这样调用回调函数:

    $progress_callback('start'); // or...
    $progress_callback('start', ['total' => $numfiles]);
    
    $progress_callback('progress', ['current' => $filename]); // or...
    $progress_callback('progress', ['total' => $numfiles, 'current' => $numcurrent, 'currentfile' => $filename]);
    
    $progress_callback('finish');
    

    您可以决定将哪些数据传递给进度回调,以及在处理程序中使用它一次。

    现在,为了能够通过AJAX获得进度,您必须创建一个独立于HTTP请求运行的任务。您返回任务ID,并使用AJAX轮询该ID的进度。

    在服务器中,您必须使用某种队列/任务系统,例如Laravel queues。这只是一个例子;你可以谷歌了解更多。

    在函数回调中,您可以保存到磁盘/ redis /当前任务的进度。