我正在尝试在我的php CLI应用程序上运行“实时”进度指示器。而不是输出为
1Done
2Done
3Done
我希望它清除并显示最新结果。 system(“command \ C CLS”)不起作用。也没有ob_flush(),flush()或我发现的任何其他内容。
我正在运行Windows 7 64位终极版,我注意到命令行实时输出,这是出乎意料的。每个人都警告我,不会...但它确实...... 64位特权?
欢呼帮助!
如果可以,我想避免回复24条新线。
答案 0 :(得分:98)
尝试输出一行文本并以“\ r”而不是“\ n”结束。
“\ n”字符是一个换行符,它转到下一行,但“\ r \ n”只是一个返回,它将光标发送回同一行的位置0。
所以你可以:
echo "1Done\r";
echo "2Done\r";
echo "3Done\r";
等
确保在“\ r”之前输出一些空格以清除该行的先前内容。
[编辑]可选:对某些历史感兴趣&背景?维基百科在"\n" (line feed)和"\r" (carriage return)
上有很好的文章答案 1 :(得分:29)
我在寻找这个问题的多线解决方案时遇到了这个问题。这就是我最终提出的。您可以使用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);
}
?>
答案 2 :(得分:8)
我最近编写了一个函数,它还会跟踪它上次输出的行数,因此您可以使用换行符提供任意字符串长度,它将使用当前行替换最后一个输出。
使用字符串数组:
$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',
);
可以使用以下功能:
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 "\033[K";
// Move cursor Up a line
echo "\033[1A";
// Return to the beginning of the line
echo "\r";
// Erase to the end of the line
echo "\033[K";
// Return to the beginning of the line
echo "\r";
// Can be consolodated into
// echo "\r\033[K\033[1A\r\033[K\r";
}
$last_lines = $line_count;
echo $message."\n";
}
循环:
foreach($lines as $line) {
replaceable_echo($line);
sleep(1);
}
并且所有行都互相替换。
该功能的名称可以使用一些工作,只是鞭打它,但这个想法是合理的。将它作为第二个参数输入(int),它将替换上面的那么多行。如果您在其他输出之后打印,并且您不想替换错误的行数(或者任何,给它0),这将非常有用。
Dunno,对我来说似乎是一个很好的解决方案。
我确保回显结束换行符,这样它允许用户仍然使用echo
/ print_r
而不会删除该行(使用覆盖不删除此类输出),以及命令提示符会回到正确的地方。
答案 3 :(得分:5)
类似的东西:
for ($i = 0; $i <= 100; $i++) {
echo "Loading... {$i}%\r";
usleep(10000);
}
答案 4 :(得分:5)
function clearTerminal () {
if (strncasecmp(PHP_OS, 'win', 3) === 0) {
popen('cls', 'w');
} else {
exec('clear');
}
}
在Win 7 PHP 7上测试。根据其他用户的报告,Linux的解决方案应该可行。
答案 5 :(得分:2)
我知道问题不仅仅在于如何在PHP中清除单行,但这是Google清除“ cli cli cli php”的最佳结果,因此这是如何清除单行:
function clearLine()
{
echo "\033[2K\r";
}
答案 6 :(得分:1)
控制台功能与平台有关,因此PHP没有内置函数来处理这个问题。 system
和其他类似函数在这种情况下不起作用,因为PHP捕获这些程序的输出并打印/返回它们。 PHP打印到标准输出的内容和不直接到控制台,因此“打印”cls
的输出将无效。
答案 7 :(得分:1)
<?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--;
}
?>
@dkamins答案的简单实现。它运作良好。这有点像黑客。但是这份工作。不会跨多行工作。
答案 8 :(得分:0)
使用此命令清除cli:
echo chr(27).chr(91).'H'.chr(27).chr(91).'J'; //^[H^[J
答案 9 :(得分:0)
尝试了答案中的一些解决方案:
<?php
...
$messages = [
'11111',
'2222',
'333',
'44',
'5',
];
$endlines = [
"\r",
"\033[2K\r",
"\r\033[K\033[1A\r\033[K\r",
chr(27).chr(91).'H'.chr(27).chr(91).'J',
];
foreach ($endlines as $i=>$end) {
foreach ($messages as $msg) {
output()->write("$i. ");
output()->write($msg);
sleep(1);
output()->write($end);
}
}
\033[2K\r
似乎是正确的。
答案 10 :(得分:0)
不幸的是,PHP 8.0.2 没有一个函数可以做到这一点。但是,如果您只想清除控制台,请尝试以下操作:print("\033[2J\033[;H");
或使用:popen('cls', 'w');
在 php 8.0.2 和 windows 10 下都可以使用。system('cls')
使用 c 语言编程是一样的。