Я не запускал ваш, но просто прочитав его, я думаю, что есть несколько вещей, которые очень не так с ним.
- Сессии.Вы не используете их правильно.
Значения сеанса должны быть установлены только один раз, то есть перед тем, как вы выполните $_SESSION['countdown'] = $time*60;
и $_SESSION['time_started'] = time();
, вы должны проверить, существуют ли они уже или нет, и назначить только, если они не существуют.Ваш текущий код сбрасывает часы при каждом обновлении страницы, что отрицательно сказывается на назначении сеансов.
abs
.Я думаю, что вы тоже не используете их правильно.
Вы не должны абс все оставшиеся секунды постоянно.$remainingSeconds = abs($_SESSION['countdown'] - $timeSince);
должно быть разрешено переходить в минус.Отрицательные оставшиеся секунды означают, что ваш тайм-аут истек / вы его пропустили!Вызов abs
означает, что вы фактически позволяете ему идти навсегда, если вы случайно пропустите точное время вашего мероприятия. Это ответ на вашу главную проблему .Исправьте это, и ваш счетчик перестанет работать на ноль и снова поднимется.
Вы полагаетесь на правильность проверки кода каждую секунду.Но это не так.
Отвратительные десятичные числа, которые вы получаете, когда по какой-то причине ваш код задерживается и неправильно проверяет 60-ую секунду, что означает, что ваше деление на 60 не идеальнораунд, и вы получите 8,7166666 минут.
Если вы начнете с удаления вызовов abs
и, как правило, попытаетесь немного упростить свой код, я полагаю, вы быстро добьетесь его правильной работы.
// Редактировать 1
Это очень наивный, но упрощенный подход к вашей проблеме.Я оставил там два разных выхода, чтобы вы могли выбрать один.
function timer($time) {
echo "$time minutes countdown starts." . PHP_EOL;
// Save the date in future when the timer should stop
$endTime = time() + $time * 60;
// Keeps track of last full minute to simplify logs
$lastFullMinute = $time;
while(true) {
$timeRemaining = $endTime - time();
if ($timeRemaining <= 0) {
// Time remaining is less than zero, which means we've gone beyond the end date.
// End the loop
return;
}
// Round up!
$minutesRemaining = ceil($timeRemaining / 60);
if ($minutesRemaining != $lastFullMinute) {
// Current "minute" is different than the previous one, so display a nice message
// If you want to show how many minutes are remainig, use this:
echo "$minutesRemaining minutes remaining." . PHP_EOL;
// If you want to show how many minutes have passed, you have to take mintutesRemaining away from the original time
$minutesPassed = $time - $minutesRemaining;
echo "$minutesPassed minutes passed." . PHP_EOL;
$lastFullMinute = $minutesRemaining;
}
}
}
Основной способ дальнейшего улучшения - использование функции sleep
http://php.net/manual/en/function.sleep.php. В настоящее время while loop
будет загружать весь процессор, постоянно проверяя, произошел ли таймер, поэтому вы должны поспать несколько секунд внутри.