Небольшой служебный класс, помогающий ограничить время выполнения скрипта.
Класс обычно используется в циклах с большими затратами времени.
// maximum time to execute one request
$ REQUEST_TIMEOUT_SEC = 5 ;
$ curlClient = new SomeCurlClient (); // just an example.
// shared hosting often has a limit. E.g. 30 seconds
$ maxExecutionTime = ini_get ( ' max_execution_time ' );
$ timeLimiter = new timelimiter TimeLimiter ( $ maxExecutionTime , $ REQUEST_TIMEOUT_SEC );
// check if there is time left to prevent 504 timeout
// recommended
foreach ( $ timeLimiter => $ timeLeft ){
$ result = $ curlClient -> doSomeHeavyJob ([
' timeout ' => $ REQUEST_TIMEOUT_SEC
]);
// handle the result
// ...
}
// or alternatively while loop might be used with respective Iterator calls.
while ( $ timeLimiter -> valid ()){
$ result = $ curlClient -> doSomeHeavyJob ([
' timeout ' => $ REQUEST_TIMEOUT_SEC
]);
$ timeLimiter -> next (); // must be called to adapt to long iterations
}
В качестве производственной зависимости с использованием Composer:
composer require morjodrom/time-limiter
В качестве зависимости от разработки для случаев, связанных только с разработкой:
composer require --dev morjodrom/time-limiter
int $limitSeconds
— секунды на обработку. 0 означает отсутствие ограничений. Значение из ini_get('max_execution_time')
может быть желаемым вариантом.
[int $preliminaryTimeout] = DEFAULT_TIME_UP_SECONDS = 3
секунды для предварительной остановки выполнения до достижения таймаута. $preliminaryTimeout
должно быть немного больше, чем самая длинная теоретическая операция, выполняемая в цикле. Поэтому последняя рискованная операция, которая может превысить время выполнения, опускается. Класс отслеживает время, затрачиваемое на каждую итерацию, чтобы обновить $preliminaryTimeout, чтобы он соответствовал самой длинной операции.
[int|null $startTimestamp = $_SERVER['REQUEST_TIME']
используется по умолчанию. Должна быть метка времени начиная с эпохи Unix (1 января 1970 г., 00:00:00 по Гринвичу), например, вызов time()
. Настоятельно рекомендуется использовать конструкцию foreach
. while
итерация также возможна при правильных вызовах Iterator.
current(): int
— возвращает количество секунд, оставшихся до истечения тайм-аута valid(): bool
— возвращает, если осталось время для безопасного выполнения сценария next(): void
— необходимо вызывать после завершенной итерации, чтобы адаптироваться к неожиданно длинным итерациям
Не стесняйтесь открывать проблему: https://github.com/Morjodrom/time-limiter/issues.