den1008 / progress-status
Calculating progress
Installs: 4 749
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 это простой в использовании компонент для расчета общего процента выполнения задачи многомодульных программ на 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/