Таймер сеанса PHP работает изначально, но ушел неправильно - PullRequest
0 голосов
/ 25 декабря 2018

Итак, у меня есть таймер php-сессии, который работает, но каким-то образом выходит из строя через некоторое время ... это код и журнал консоли, который я получил.Я ищу решение этой проблемы или, возможно, другой набор кода для достижения того же эффекта таймера (поскольку я не уверен, что использование сеанса является лучшим методом для таймера)

session_start();
function timer($time) {
        //Set the countdown to 120 seconds.
    $_SESSION['countdown'] = $time*60;
        //Store the timestamp of when the countdown began.
    $_SESSION['time_started'] = time();

    $now = time();
    $timeSince = $now - $_SESSION['time_started'];
    $remainingSeconds = abs($_SESSION['countdown'] - $timeSince);
    $counter = 0; 

    $minutes = $remainingSeconds/60;
    echo "$minutes minutes countdown starts.".PHP_EOL;
    while($remainingSeconds >= 1) {
        $now = time();
        $timeSince = $now - $_SESSION['time_started'];

        if (($timeSince-$counter) >= 60) {
            $remainingSeconds = abs($_SESSION['countdown'] - $timeSince);
            $counter = $timeSince;
            $minutes = $remainingSeconds/60;
            echo "$minutes minutes has passed.".PHP_EOL;
        }
    }

    if($remainingSeconds < 1){
        session_abort(); 
        return true;
    }
}

if($this->timer(30)) {
        // do whatever
        echo "$time has passed";
    }

Вот что происходит в консоли:

30 minutes countdown starts.
29 minutes has passed.
.... (continue as per pattern)
16 minutes has passed.
15 minutes has passed. (problem occurs here)
8.7166666666667 minutes has passed.
7.7166666666667 minutes has passed.
6.7166666666667 minutes has passed.
.... (continue as per pattern)
0.71666666666667 minutes has passed.
0.28333333333333 minutes has passed.
1.2833333333333 minutes has passed.
2.2833333333333 minutes has passed.
.... (continue as per pattern all the way)

Дополнительные примечания: Таймер сеанса не всегда повторяет один и тот же шаблон, были случаи, когда он пробегал все 30 минут иудалось повторить "время $ прошло"; , а ошибка произошла только позже

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Что вы думаете об этом решении?ссылка сверху

function timer($time) {
echo "$time minutes countdown starts." . PHP_EOL;

// Save the date in future when the timer should stop
$endTime = time() + $time*60;

while(true) {
    sleep(20);
    $secondsRemaining = $endTime - time();

    if ($secondsRemaining <= 0) {
        echo 'Finished';
        return true;
        }
    }
}
0 голосов
/ 25 декабря 2018

Я не запускал ваш, но просто прочитав его, я думаю, что есть несколько вещей, которые очень не так с ним.

  1. Сессии.Вы не используете их правильно.

Значения сеанса должны быть установлены только один раз, то есть перед тем, как вы выполните $_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 будет загружать весь процессор, постоянно проверяя, произошел ли таймер, поэтому вы должны поспать несколько секунд внутри.

...