清除 PHP CLI 输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4320081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:39:34  来源:igfitidea点击:

Clear PHP CLI output

php

提问by dkamins

I'm trying to get a "live" progress indicator working on my php CLI app. Rather than outputting as

我正在尝试在我的 php CLI 应用程序上获得一个“实时”进度指示器。而不是输出为

1Done
2Done
3Done

I would rather it cleared and just showed the latest result. system("command \C CLS") doesnt work. Nor does ob_flush(), flush() or anything else that I've found.

我宁愿它清除并显示最新的结果。system("command \C CLS") 不起作用。也没有 ob_flush()、flush() 或我发现的任何其他东西。

I'm running windows 7 64 bit ultimate, I noticed the command line outputs in real time, which was unexpected. Everyone warned me that out wouldn't... but it does... a 64 bit perk?

我正在运行 Windows 7 64 位终极版,我实时注意到命令行输出,这是出乎意料的。每个人都警告我说不会......但它确实...... 64位振作?

Cheers for the help!

为帮助干杯!

I want to avoid echoing 24 new lines if I can.

如果可以,我想避免回显 24 个新行。

回答by dkamins

Try outputting a line of text and terminating it with "\r" instead of "\n".

尝试输出一行文本并用“\r”而不是“\n”终止它。

The "\n" character is a line-feed which goes to the next line, but "\r" is just a return that sends the cursor back to position 0 on the same line.

"\n" 字符是一个换行符,它转到下一行,但 "\r" 只是一个返回,将光标发送回同一行的位置 0。

So you can:

这样你就可以:

echo "1Done\r";
echo "2Done\r";
echo "3Done\r";

etc.

等等。

Make sure to output some spaces before the "\r" to clear the previous contents of the line.

确保在“\r”之前输出一些空格以清除该行的先前内容。

[Edit] Optional: Interested in some history & background? Wikipedia has good articles on "\n" (line feed)and "\r" (carriage return)

[编辑] 可选:对一些历史和背景感兴趣?维基百科有关于“\n”(换行)“\r”(回车)的好文章

回答by nolanpro

I came across this while searching for a multi line solution to this problem. This is what I eventually came up with. You can use Ansi Escape commands. http://www.inwap.com/pdp10/ansicode.txt

我在寻找解决此问题的多行解决方案时遇到了这个问题。这是我最终想到的。您可以使用 Ansi Escape 命令。http://www.inwap.com/pdp10/ansicode.txt

<?php
function replaceOut($str)
{
    $numNewLines = substr_count($str, "\n");
    echo chr(27) . "[0G"; // Set cursor to first column
    echo $str;
    echo chr(27) . "[" . $numNewLines ."A"; // Set cursor up x lines
}

while (true) {
    replaceOut("First Ln\nTime: " . time() . "\nThird Ln");
    sleep(1);
}
?>

回答by Mike

I recently wrote a function that will also keep track of the number of lines it last output, so you can feed it arbitrary string lengths, with newlines, and it will replace the last output with the current one.

我最近编写了一个函数,它还会跟踪上次输出的行数,因此您可以使用换行符为它提供任意长度的字符串,并且它将用当前输出替换上一次输出。

With an array of strings:

使用字符串数组:

$lines = array(
    'This is a pretty short line',
    'This line is slightly longer because it has more characters (i suck at lorem)',
    'This line is really long, but I an not going to type, I am just going to hit the keyboard... LJK gkjg gyu g uyguyg G jk GJHG jh gljg ljgLJg lgJLG ljgjlgLK Gljgljgljg lgLKJgkglkg lHGL KgglhG jh',
    "This line has newline characters\nAnd because of that\nWill span multiple lines without being too long",
    "one\nmore\nwith\nnewlines",
    'This line is really long, but I an not going to type, I am just going to hit the keyboard... LJK gkjg gyu g uyguyg G jk GJHG jh gljg ljgLJg lgJLG ljgjlgLK Gljgljgljg lgLKJgkglkg lHGL KgglhG jh',
    "This line has newline characters\nAnd because of that\nWill span multiple lines without being too long",
    'This is a pretty short line',
);

One can use the following function:

可以使用以下功能:

function replaceable_echo($message, $force_clear_lines = NULL) {
    static $last_lines = 0;

    if(!is_null($force_clear_lines)) {
        $last_lines = $force_clear_lines;
    }

    $term_width = exec('tput cols', $toss, $status);
    if($status) {
        $term_width = 64; // Arbitrary fall-back term width.
    }

    $line_count = 0;
    foreach(explode("\n", $message) as $line) {
        $line_count += count(str_split($line, $term_width));
    }

    // Erasure MAGIC: Clear as many lines as the last output had.
    for($i = 0; $i < $last_lines; $i++) {
        // Return to the beginning of the line
        echo "\r";
        // Erase to the end of the line
        echo "3[K";
        // Move cursor Up a line
        echo "3[1A";
        // Return to the beginning of the line
        echo "\r";
        // Erase to the end of the line
        echo "3[K";
        // Return to the beginning of the line
        echo "\r";
        // Can be consolodated into
        // echo "\r3[K3[1A\r3[K\r";
    }

    $last_lines = $line_count;

    echo $message."\n";
}

In a loop:

在一个循环中:

foreach($lines as $line) {
    replaceable_echo($line);
    sleep(1);
}

And all lines replace each other.

并且所有行相互替换。

The name of the function could use some work, just whipped it up, but the idea is sound. Feed it an (int) as the second param and it will replace that many lines above instead. This would be useful if you were printing after other output, and you didn't want to replace the wrong number of lines (or any, give it 0).

该函数的名称可能需要一些工作,只是将其掀起,但这个想法是合理的。给它一个 (int) 作为第二个参数,它将替换上面的许多行。如果您在其他输出之后打印,并且您不想替换错误的行数(或任何行数,将其设为 0),这将非常有用。

Dunno, seemed like a good solution to me.

不知道,对我来说似乎是一个很好的解决方案。

I make sure to echo the ending newline so that it allows the user to still use echo/print_rwithout killing the line (use the override to not delete such outputs), and the command prompt will come back in the correct place.

我确保回显结束换行符,以便它允许用户仍然使用echo/print_r而不终止该行(使用覆盖不删除此类输出),并且命令提示符将返回到正确的位置。

回答by Alexander Shostak

function clearTerminal () {
  DIRECTORY_SEPARATOR === '\' ? popen('cls', 'w') : exec('clear');
}

Tested on Win 7 PHP 7. Solution for Linux should work, according to other users reports.

在 Win 7 PHP 7 上测试。根据其他用户报告,Linux 解决方案应该可以工作。

回答by hanshenrik

i know the question isn't strictly about how to clear a SINGLE LINE in PHP, but this is the top google result for "clear line cli php", so here is how to clear a single line:

我知道这个问题严格来说不是关于如何在 PHP 中清除单行,但这是“清除行 cli php”的顶级谷歌结果,所以这里是如何清除单行:

function clearLine()
{
    echo "3[2K\r";
}

回答by Bruno Ribeiro

something like this :

像这样:

for ($i = 0; $i <= 100; $i++) {
    echo "Loading... {$i}%\r";
    usleep(10000);
}

回答by Nabi K.A.Z.

Use this command for clear cli:

使用此命令清除 cli:

echo chr(27).chr(91).'H'.chr(27).chr(91).'J';   //^[H^[J  

回答by casablanca

Console functions are platform dependent and as such PHP has no built-in functions to deal with this. systemand other similar functions won't work in this case because PHP captures the output of these programs and prints/returns them. What PHP prints goes to standard output and notdirectly to the console, so "printing" the output of clswon't work.

控制台函数是平台相关的,因此 PHP 没有内置函数来处理这个问题。system和其他类似的函数在这种情况下将不起作用,因为 PHP 捕获这些程序的输出并打印/返回它们。PHP 打印到标准输出而不是直接到控制台,因此“打印” 的输出cls将不起作用。

回答by casablanca

<?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);

function bufferout($newline, $buffer=null){
    $count = strlen(rtrim($buffer));
    $buffer = $newline;
    if(($whilespace = $count-strlen($buffer))>=1){
        $buffer .= str_repeat(" ", $whilespace);
    }
    return $buffer."\r"; 
};

$start = "abcdefghijklmnopqrstuvwxyz0123456789";
$i = strlen($start);

while ($i >= 0){
    $new = substr($start, 0, $i);
    if($old){
        echo $old = bufferout($new, $old);
    }else{
        echo $old = bufferout($new);
    }
    sleep(1);
    $i--;
}
?>

A simple implementation of @dkamins answer. It works well. It's a bit- hack-ish. But does the job. Wont work across multiple lines.

@dkamins 答案的简单实现。它运作良好。这有点hack-ish。但是可以完成工作。不能跨多行工作。