Update Command-line Output, i.e. for Progress
Asked Answered
C

2

71

I'd like to be able to show a progress meter in a simple PHP script on the command line. Instead of seeing

Progress: 0%
Progress: 1%
etc...

I'd like just the number to change, and replace the previous number, much like git clone does for example Resolving deltas: 100% (8522/8522), done..

While searching for this I found the same question answered in Perl, which is perfect, but I couldn't find it in PHP. Is it possible? If not, I'll resort to C.

Thanks

Update: If anyone's interested in the C++ version, it's here.

Coinage answered 10/3, 2011 at 20:7 Comment(12)
usually php has finished its job before anything is sent to the browser, what's the script doing?Salmi
@Dagon he is using command-lineCereus
doh! thanks, sounds even odder then the only php command line i do is for me, its hardly suitable for a user interface.Salmi
Yes, it's on the command-line. It's just for simple scripts, for personal use: updating project version number, transferring files somewhere, etc.. Nothing user-facingCoinage
seems pointless to then add a progress bar. But then i'm always function over form.Salmi
@Dagon Well, I suppose there is a user - me. Sometimes it's nice to have an idea of how long something might take. And in this case, form doesn't impeed function, afaikCoinage
real men don't need pretty progress bars :-)Salmi
I just released my progressbar implementation github.com/Ex3v/PHP-ProgressBarEvacuee
https://mcmap.net/q/276288/-clear-php-cli-outputSphere
@Coinage Please consider changing best answer.Elect
@Arek which would you suggest. Any reason?Coinage
"\r" looks simple and clean, but "\033" gives more control. Never mind.Elect
C
112

This can be done using ANSI Escape Sequences -- see here for a list.

In PHP, you'll use "\033" when it's indicated ESC on that page.


In your case, you could use something like this :

echo "Progress :      ";  // 5 characters of padding at the end
for ($i=0 ; $i<=100 ; $i++) {
    echo "\033[5D";      // Move 5 characters backward
    echo str_pad($i, 3, ' ', STR_PAD_LEFT) . " %";    // Output is always 5 characters long
    sleep(1);           // wait for a while, so we see the animation
}


I simplified a bit, making sure I always have 5 extra characters, and always displaying the same amount of data, to always move backwards by the same number of chars...

But, of course, you should be able to do much more complicated, if needed ;-)

And there are many other interesting escape sequences : colors, for instance, can enhance your output quite a bit ;-)

Cereus answered 10/3, 2011 at 20:19 Comment(2)
PHP > 5.4.0 now have "\e" to write ESCLinear
this one works in windows https://mcmap.net/q/276288/-clear-php-cli-outputSphere
W
93

Just for the record though an old thread: Instead of using fancy ANSI Escape sequencing to move the curser back I just move it back to the beginning of the line using "\r" instead of to the beginning of the next line "\n". Add a few spaces after your echo to overwrite anything that was there previously, like e.g. so:

for ($i=0 ; $i<=100 ; $i++) {
  echo "Progress: $i %   \r";
  sleep(1);
}
Wehrmacht answered 13/11, 2016 at 9:31 Comment(7)
Works like a charm, also on Windows! (tested)Ephraim
Much easier than the solution with the most upvotes - works perfectly on OSX.Diverticulitis
much better solutionMiraflores
also you can use usleep for big collectionAlly
you're a genius ! Works fine in Windows command line window !Nasia
This probably doesn't answer the original question better than the accepted answer, BUT it is likely more useful for what most people are looking for when they come across this question.Fink
That's amazing!very useful!Dryfoos

© 2022 - 2024 — McMap. All rights reserved.