den1008 / progress-status
Calculating progress
Installs: 4 692
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: >=7.0
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ~6.0 || ~7.0 || ~8.0 || ~9.0
README
ProgressStatus ======
ProgressStatus это простой в использовании компонент для расчета общего процента выполнения задачи многомодульных программ на PHP.
Установка
$ composer require den1008/progress-status
Использование -----Основным элементом является StatusProcessor, который реализует функции просчета прогресса и которому необходимо передавать хэндлеры, в зависимости от того, куда необходимо выводить информацию о прогрессе. На данный момент есть 2 хэндлера: StdOutStatus и FileStatus, но вы можете написать и свои по аналогии.
StatusProcessor
Для того чтобы уведомить пользователя о изменении прогресса выполнения есть два метода say() или sayStage()
$status->say(); //Вывод сообщений об изменении прогресса
$status->sayStage(); //Вывод сообщений об изменении этапа выполнения
Замечание! Все хэндлеры должны реализовать интерфейс IStatusHandler (методы sayStageConcrete() и sayConcrete(), а не методы sayStage() и say()). Это сделано для того, чтобы иметь возможность отсекать часть сообщений для хэндлеров. Пример:
$processor = new StatusProcessor([new SomeStatusHandler()]);
$processor->setTotal(100)
->setStepProcessingProgress(25); //Теперь все хэндлеры будут получать сообщения с шагом 25%
for ($i = 0; $i < 100; $i++){
$processor->increaseProgress()->say('processing');
}
Вывод SomeStatusHandler
[I completed 25%] processing
[I completed 50%] processing
[I completed 75%] processing
[I completed 100%] processing
Подсчет статистики во вложенных подпрограммах с помощью метода wrapSubProgram(Closure $func, $endProgress), где $func - это запускаемая подпрограмма, а $endProgress - прогресс, который будет достигнут по завершению подпрограммы. Пример использования:
$processor = new StatusProcessor([new SomeStatusHandler()]);
//Необходимо обязательно задавать общее количество, иначе будет выброшено исключение.
//$processor->getNested() == 1 глубина вложенности
$processor->setTotal(1000);
//{%total%} = 1000
for ($i = 0; $i <= 20; $i += 10) {
$processor->setProgress($i * 10);
//$i=0 --> {%percent%} = 0%, {%progress%} = 0, {%commonPercent%} = 0%
//$i=10 --> {%percent%} = 10%, {%progress%} = 100, {%commonPercent%} = 10%
//$i=20 --> {%percent%} = 20%, {%progress%} = 200, {%commonPercent%} = 20%
$processor->say('Процесс 1 {%percent%}% элементов ({%progress%} из {%total%})');
}
//Запуск подпрограммы
$processor->wrapSubProgram(function (StatusProcessor $processor){
//$processor->getNested() == 2 глубина вложенности
//Подпрограмма ничего не знает о родительском статусе выполнения, поэтому ведет собственный расчет от 0 до {%total%}
//Если не указать общее количество, процент выполнения будет равен 100%.
$processor->setTotal(50);
//{%total%} = 50
for ($i = 0; $i < 5; $i++) {
$processor->increaseProgress(10);
//$i=0 --> {%percent%} = 20%, {%progress%} = 10, {%commonPercent%} = 28%
//$i=1 --> {%percent%} = 40%, {%progress%} = 20, {%commonPercent%} = 36%
//$i=2 --> {%percent%} = 60%, {%progress%} = 30, {%commonPercent%} = 44%
//$i=3 --> {%percent%} = 80%, {%progress%} = 40, {%commonPercent%} = 52%
//$i=4 --> {%percent%} = 100%, {%progress%} = 50, {%commonPercent%} = 60%
//Здесь параметры {%progress%} из {%total%} будут для текущего контекста, но {%commonPercent%}% - для общего
$processor->say('Процесс 2 {%commonPercent%}% элементов ({%progress%} из {%total%})');
}
}, 600); //Здесь 600 - прогресс который будет достигнут после выполнения подпрограммы
//$processor->getNested() == 1 глубина вложенности
//{%commonPercent%} == {%percent%} == 60%, т.к. ни одна подпрограмма не была обернута
//{%progress%} = 600
//{%total%} = 1000
for ($i = 60; $i <= 100; $i += 10) {
$processor->setProgress($i * 10);
//$i=60 --> {%percent%} = 60% {%progress%} = 600, {%commonPercent%} = 60%
//$i=70 --> {%percent%} = 70% {%progress%} = 700, {%commonPercent%} = 70%
//$i=80 --> {%percent%} = 80% {%progress%} = 800, {%commonPercent%} = 80%
//$i=90 --> {%percent%} = 90% {%progress%} = 900, {%commonPercent%} = 90%
//$i=100 --> {%percent%} = 100% {%progress%} = 1000, {%commonPercent%} = 100%
$processor->say('Процесс 1 {%percent%}% элементов ({%progress%} из {%total%})');
}
StdOutStatusHandler ~~~~~~~~~~~~~~~~~
Данный компонент выводит информацию о прогрессе в std. Простой пример использования выглядит следующим образом:
use den1008\ProgressStatus\handlers\StdOutStatusHandler;
// define status
$processor = new StatusProcessor([new StdOutStatusHandler()]);
$processor->setTotal(100);
for ($i = 0; $i < 100; $i++){
$processor->increaseProgress()->say('processing');
}
При выполнении скрипта в консоль будут выведены следующие строки:
[2019-04-16 19:36:51][ 1.0%][ 0.00] processing
[2019-04-16 19:36:51][ 2.0%][ 0.00] processing
...
[2019-04-16 19:36:51][100.0%][ 0.00] processing
Для того чтобы не печатать каждый раз новую строку, а изменять одну и ту же, необходимо сделать так:
$handler = new StdOutStatusHandler(0); // изменение глубины вывода вложенных прогрессов
По умолчанию глубина скрываемых вложенных прогрессов равна 1, т.е. при вызове методов say() и sayStage() каждое сообщение из глубины 1 будет выведено на новой строке. Для сообщений из глубины 2 прогресс будет выводится на одной обновляемой строке. Общий случай: если глубину скрываемых сообщений сделать равной N, то все сообщения из глубины <= N будут выводится на новой строке, а все сообщения из глубины > N на одной обновляемой строке.
Для изменения шаблонов вывода сообщений необходимо изменить следующие публичные поля класса:
/** @var string Формат вывода */
public $mainFormat = "[{%date%} {%time%}][{%commonPercent%}%][{%totalTime%}] {%msg%}";
/** @var string Формат вывода скрытых однострочных статусов */
public $hideFormat = "[{%date%} {%time%}][{%commonPercent%}%][{%totalTime%}] └ {%msg%}";
- Для форматирования сообщений используется FormatMessageTrait. Доступные параметры для вывода:
- {%date%} - текущая дата
- {%time%} - текущее время
- {%progress%} - текущий прогресс
- {%total%} - максимальный прогресс
- {%time%} - текущее время
- {%percent%} - текущий процент выполнения
- {%commonPercent%} - общий процент выполнения
- {%totalTime%} - общее время (от начала момента работы) выполнения на каждом шаге
- {%stepTime%} - затраченое время (от момента последнего шага) на каждом шаге
- {%msg%} - сообщение
FileStatusHandler
Данный компонент выводит информацию о прогрессе в файл. Простой пример использования выглядит следующим образом:
use den1008\ProgressStatus\handlers\FileStatusHandler;
// define status
$processor = new StatusProcessor([new FileStatusHandler('path/to/file')]);
$processor->setTotal(100);
for ($i = 0; $i < 100; $i++){
$processor->increaseProgress()->say('processing');
}
При выполнении скрипта в файл будут записаны следующие строки:
[2019-04-16 19:36:51][ 1.0%] processing
[2019-04-16 19:36:51][ 2.0%] processing
...
[2019-04-16 19:36:51][100.0%] processing
Для изменения шаблона вывода сообщений необходимо изменить следующее поле класса:
/** @var string Формат вывода */
public $format = "[{%date%} {%time%}][{%commonPercent%}] {%msg%}";
Для форматирования сообщений, как и в StdOutStatusHandler, используется FormatMessageTrait (см. описание выше).
Test
Для тестирования используется PhpUnit
./vendor/bin/phpunit tests/