当前位置:  开发笔记 > 编程语言 > 正文

PHP中的命令行进度条

如何解决《PHP中的命令行进度条》经验,为你挑选了2个好方法。

我目前正在尝试向命令行脚本添加进度条,我尝试了各种解决方案(包括Zend和Console_ProgressBar).它们两者有共同的问题是进度条不会粘在窗口的底部,因为在脚本中,输出新行和其他信息.

有没有办法让进度条保持在终端的底部,但仍然能够在脚本运行时输出其他信息?

[编辑]

我想到了:

而不是直接输出到STDOUT我实际上是抓取变量内的输出,我擦除屏幕echo chr(27) . '[2J'然后输出到STDOUT变量的内容然后追加我的进度条.

希望有道理:)



1> user956584..:

这是cli很好的进度条:

http://snipplr.com/view/29548/


 * for($x=1;$x<=100;$x++){
 * 
 *     show_status($x, 100);
 * 
 *     usleep(100000);
 *                           
 * }
 * 
 *
 * @param   int     $done   how many items are completed
 * @param   int     $total  how many items are to be done total
 * @param   int     $size   optional size of the status bar
 * @return  void
 *
 */

function show_status($done, $total, $size=30) {

    static $start_time;

    // if we go over our bound, just ignore it
    if($done > $total) return;

    if(empty($start_time)) $start_time=time();
    $now = time();

    $perc=(double)($done/$total);

    $bar=floor($perc*$size);

    $status_bar="\r[";
    $status_bar.=str_repeat("=", $bar);
    if($bar<$size){
        $status_bar.=">";
        $status_bar.=str_repeat(" ", $size-$bar);
    } else {
        $status_bar.="=";
    }

    $disp=number_format($perc*100, 0);

    $status_bar.="] $disp%  $done/$total";

    $rate = ($now-$start_time)/$done;
    $left = $total - $done;
    $eta = round($rate * $left, 2);

    $elapsed = $now - $start_time;

    $status_bar.= " remaining: ".number_format($eta)." sec.  elapsed: ".number_format($elapsed)." sec.";

    echo "$status_bar  ";

    flush();

    // when done, send a newline
    if($done == $total) {
        echo "\n";
    }

}

?>


这是最好的答案
非常如此.总而言之,该代码片段的重要部分是在写出新行之前回显出`"\ r"`(需要双引号).
该功能最糟糕的是,您通常使用$ c = 0而不是$ c = 1来启动for循环。由于您以$ c = 0开头,因此该函数会得到除以零的异常。

2> MacroMan..:

其他答案似乎过于复杂.我的解决方案是在下次更新之前简单地回显\ 033 [0G转义序列,它将光标移回到开头.

function progressBar($done, $total) {
    $perc = floor(($done / $total) * 100);
    $left = 100 - $perc;
    $write = sprintf("\033[0G\033[2K[%'={$perc}s>%-{$left}s] - $perc%% - $done/$total", "", "");
    fwrite(STDERR, $write);
}

首次调用该函数会输出进度条,每次后续调用都会用新的进度条覆盖最后一行.

编辑:我已经改变了回显\ r到转义序列\ 033 [0G,现在这应该适用于OSX以及Linux/Unix.

编辑2:根据@tbjers建议修正了第3行可能出现的错误.

编辑3:更新了新版本,打印到STDERR,现在也在GitHub上:https://github.com/MacroMan/PHPTerminalProgressBar

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有