Php Cli Progress Bar
Sep 16, 2016 · 2 minute readCategory: PHP
I’ve been doing a lot of data manipulation on the command line recently, and one of bugbears that I ran into was that my commands gave no indication of how long they were going to take to complete.
Sick and tired of just looking at the blank screen I put together a small progress bar class that can be used indicate how many items have been processed.
class ProgressBar
{
protected $_spinners = ['|', '/', '-', '\\', '|', '/', '-', '\\'];
/**
* This is used to echo the progress of a task on the command line.
* Pass in the current row that you are on and the number of rows that need to be processed and this will echo out
* a progress bar like this
*
* Progress: [-----------------\ ]
*
* It is possible to change the width of the bar by passing in an int as the $steps param, otherwise this default
* to 60
*
* Once the process is complete pass in the $last param as true to finish the the process bar
*
* @param $totalDone - The number of rows that have been processed so far
* @param $total - The total number of rows to be processed
* @param bool $last - If the process has been completed
* @param bool $steps - How wide the process bar should be
*/
public function echoProgress($totalDone, $total, $last = false, $steps = false)
{
if (PHP_SAPI != 'cli') {
return;
}
$steps = ($steps == false) ? 60 : $steps;
if ($last === true) {
$display = "Progress: [" . str_repeat('-', $steps + 1) . "]\r";
} else {
$toGo = floor((1 - ($totalDone / $total)) * $steps);
$progressBar = str_repeat('-', $steps - $toGo);
$emptySpace = str_repeat(' ', $toGo);
$index = $totalDone % 8;
$display = "Progress: [" . $progressBar . $this->_spinners[$index] . $emptySpace . "]\r";
}
// @codingStandardsIgnoreStart - There's nothing wrong with using echo on the CLI
echo $display;
// @codingStandardsIgnoreEnd
}
}
This can then be used like so
$totalDone = 0;
$rowsToProcess = $this->getRowsToProcess();
$numberOfRowsToProcess = count($rowsToProcess);
$processBar = new ProcessBar();
foreach ($rowsToProcess as $row) {
$this->processRow($row);
$processBar->echoProgress(++$totalDone, $numberOfRowsToProcess);
}
$processBar->echoProgress(++$totalDone, $numberOfRowsToProcess, true);
Which will give the following output when run
ross@ross:~/localhost/tests $ php importData.php
starting the import of EdmondsCommerce\ProductImport\Model\OptionValues
starting the import of EdmondsCommerce\ProductImport\Model\Products
starting the import of EdmondsCommerce\ProductImport\Model\Combinations
Progress: [-----------------\ ]