Я пытаюсь получить «живой» индикатор прогресса, работающий над моим приложением PHP CLI. Вместо того, чтобы выводить как
1Done 2Done 3Done
Я бы предпочел, чтобы он очистился и просто показал последний результат. system ("command \ C CLS") не работает. Также не ob_flush (), flush () или что-нибудь еще, что я нашел.
Я запускаю Windows 7 64-разрядной версии, я заметил, что вывод командной строки в реальном времени был неожиданным. Все предупреждали меня, что это не так … но это … 64-битный перк?
Приветствия за помощь!
Я хочу избежать повторения 24 новых строк, если смогу.
Попробуйте вывести строку текста и завершите ее с помощью «\ r» вместо «\ n».
Символ «\ n» является строкой, которая переходит к следующей строке, но «\ r» – это просто возврат, который возвращает курсор в позицию 0 в той же строке.
Так что вы можете:
echo "1Done\r"; echo "2Done\r"; echo "3Done\r";
и т.п.
Обязательно выведите некоторые пробелы перед «\ r», чтобы очистить предыдущее содержимое строки.
[Изменить] Дополнительно: Заинтересованы в некоторых историях и истории? В Википедии есть хорошие статьи о «\ n» (line feed) и «\ r» (возврат каретки)
Я столкнулся с этим, ища многолинейное решение этой проблемы. Это то, что я в итоге придумал. Вы можете использовать команды 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); } ?>
Недавно я написал функцию, которая также будет отслеживать количество строк, которые она выдает последним, поэтому вы можете кормить произвольную длину строки, с новыми строками, и она заменит последний вывод на текущий.
С массивом строк:
$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
не убивая строку (используйте переопределение, чтобы не удалять такие выходы), и командная строка вернется в нужное место.
что-то вроде этого :
for ($i = 0; $i <= 100; $i++) { echo "Loading... {$i}%\r"; usleep(10000); }
Функции консоли зависят от платформы, и поэтому у этого PHP нет встроенных функций для решения этой проблемы. system
и другие подобные функции не будут работать в этом случае, потому что PHP захватывает выходные данные этих программ и печатает / возвращает их. То, что печатает PHP, идет на стандартный вывод, а не непосредственно на консоль, поэтому «печать» вывода cls
не будет работать.
<?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. Это работает хорошо. Это бит-хаш. Но делает работу. Не будет работать через несколько строк.
function clearTerminal () { if (strncasecmp(PHP_OS, 'win', 3) === 0) { popen('cls', 'w'); } else { exec('clear'); } }
Протестировано на Win 7 PHP 7. Решение для Linux должно работать, согласно отчетам других пользователей.