Skip to content

Instantly share code, notes, and snippets.

@marcojetson
Last active May 16, 2018 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marcojetson/ff958ea450211d03f169 to your computer and use it in GitHub Desktop.
Save marcojetson/ff958ea450211d03f169 to your computer and use it in GitHub Desktop.
Simple and customisable command line progress bar in PHP
<?php
/**
* Creates a progress bar
*
* @param string $template Template to use, available placeholders are %finished, %unfinished, %percent and %eta
* @param int $width Width of the progress bar
* @return callable A function that renders the bar and takes the percent as only argument
*/
function progressBar(
$template = '[%finished>%unfinished] %percent % - ETA: %eta s',
$width = 100
)
{
$symbols = [
'finished' => '=',
'unfinished' => ' ',
'eta' => '?',
];
$template = preg_replace_callback(
'/%(' . join('|', array_keys($symbols)) . '):(\'|")(.+?)\2/',
function ($match) use (&$symbols) {
$symbols[$match[1]] = $match[3];
return '%' . $match[1];
},
$template
);
$startTime = null;
return function ($percent) use ($template, $width, $symbols, &$startTime) {
if ($startTime === null) {
if ($percent === 0) {
$startTime = microtime(true);
}
$eta = $symbols['eta'];
} else {
$elapsed = microtime(true) - $startTime;
$eta = (int) ((100 - $percent) * $elapsed / $percent);
}
$completed = round($percent * $width / 100);
$view = str_replace(
[
'%finished',
'%unfinished',
'%percent',
'%eta',
],
[
str_repeat($symbols['finished'], $completed),
str_repeat($symbols['unfinished'], $width - $completed),
$percent,
$eta,
],
$template
);
return "\033[" . strlen($view) . "D" . $view;
};
}
// usage examples
// default bar
$pb = progressBar();
for ($i = 0; $i <= 100; $i++) {
echo $pb($i);
usleep(25000);
}
echo PHP_EOL;
// colors and stuff
$custom = progressBar("\033[42m%finished:' '\033[41m%unfinished\033[0m", 50);
for ($i = 0; $i <= 100; $i++) {
echo $custom($i);
usleep(25000);
}
echo PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment