Таймер PHP - функция оценивается правильно внутри функции, но не при вызове со страницы - PullRequest
0 голосов
/ 13 апреля 2019

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

По сути, я создаю браузерную игру, и у пользователей есть «монеты» или «золото». У меня есть функция для добавления золота этому пользователю. Я пытаюсь настроить таймер действий. Сам таймер работает нормально, я разобрался, что делать с обратным отсчетом.

То, что я пытаюсь сделать прямо сейчас, - это добавить кнопку на страницу, при нажатии этой кнопки в учетную запись пользователя добавляется 10 золотых, а в будущем устанавливается таймер на две минуты (измененное время для тестирования ). Если нажать кнопку еще раз, пока она остынет, на экране появится текст, говорящий о том, сколько времени осталось до «повторного использования действия».

Вот функция добавления золота на счет игрока:

function addCoinsToUser($pdo, $user, $coins) {

    $query = $pdo->prepare('update users set user_coin = user_coin + :coin where id = :user');
    $query->bindParam(':coin', $coins);
    $query->bindParam(':user', $user);
    $query->execute();

}

$pdo - мое соединение, $user всегда будет идентификатором пользователя, $coins - количество добавляемого золота.

Следующая функция - установка таймера:

function startTimer($pdo, $user) {

    date_default_timezone_set('Europe/London');

    $timerExists = userTimerExists($pdo, $user);

    if ($timerExists == true) {

        $getTimer = $pdo->prepare('select * from timers where user = :user');
        $getTimer->bindParam(':user', $user);
        $getTimer->execute();

        $existingTimer = $getTimer->fetch();
        $timeToMeasure = $existingTimer['end_time'];

        $now = new DateTime();
        $timerEnd = new DateTime("$timeToMeasure");

        $interval = $timerEnd->diff($now);

        $timerEnded = hasTimerEnded($pdo, $user);

        echo '<br>Does the function think the timer has ended? ';
        echo $timerEnded ? 'yes' : 'no';

        if ($timerEnded == true) {

            $removeTimer = $pdo->prepare('delete from timers where user = :user');
            $removeTimer->bindParam(':user', $user);
            $removeTimer->execute();

            return '<br>timer deleted';

        } else {

            return $interval->format("<br>You cannot perform that action for another %i minutes, %s seconds");

        }


    } else {

        $time = new DateTime();
        $time->modify('+30 seconds');
        $time = $time->format('Y-m-d H:i:s');

        $query = $pdo->prepare('insert into timers (end_time, user) values (:time, :user)');
        $query->bindParam(':time', $time);
        $query->bindParam(':user', $user);
        $query->execute();

        return '<br>timer started';

    }

}

При этом используются следующие две функции, чтобы проверить, существует ли таймер для этого пользователя, а затем определить, закончился ли этот таймер. Кажется, что все работает нормально в функции выше.

function userTimerExists($pdo, $user) {

    $query = $pdo->prepare('select count(id) from timers where user = :user');
    $query->bindParam(':user', $user);
    $query->execute();

    $count = $query->fetchColumn();

    if ($count > 0) {

        return true;

    } else {

        return false;

    }

}

function hasTimerEnded($pdo, $user) {

    $getTimer = $pdo->prepare('select * from timers where `user` = :user');
    $getTimer->bindParam(':user', $user);
    $getTimer->execute();

    $existingTimer = $getTimer->fetch();
    $timeToMeasure = $existingTimer['end_time'];

    $now = new DateTime();
    $timerEnd = new DateTime("$timeToMeasure");

    //$interval = $timerEnd->diff($now);

    if ($now > $timerEnd) {

        return true;

    } else {

        return false;

    }

}

Все вышеперечисленное находится в моем файле functions.php. Ниже приведен код, используемый на странице для кнопки. Переменная $user создается в другом месте, если пользователь вошел в систему, если нет, то она не создается.

<?php

        if (isset($user)) { ?>

            <a href='index.php?get_coins=true'>Get Some Coins</a>
            <?php

        }

        if (isset($_GET['get_coins'])) {

            $hasTimer = userTimerExists($pdo, $user['id']);

            if ($hasTimer == true) {

                $ended = hasTimerEnded($pdo, $user['id']);
                echo '<br>Does the page think the timer has ended? ';
                echo $ended ? 'yes' : 'no';

                if ($ended == true) {

                    //addCoinsToUser($pdo, $user['id'], 10);
                    //startTimer($pdo, $user['id']);
                    echo 'You gained some coins.';

                } else {

                    echo startTimer($pdo, $user['id']);

                }

            } else {

                addCoinsToUser($pdo, $user['id'], 10);
                startTimer($pdo, $user['id']);
                echo '<br>coins coins coins';

            }

        }

        ?>

В настоящее время происходит следующее: если при нажатии кнопки в базе данных нет таймеров для этого пользователя, в учетную запись пользователя добавляется 10 золотых, а таймер устанавливается на 30 секунд.

Когда кнопка нажата в течение этих 30 секунд, золото не будет добавлено, и появится сообщение о том, сколько времени осталось, пока пользователь не сможет добавить еще золота.

Проблема заключается в том, что таймер истек - когда вы нажимаете кнопку и таймер заканчивается, на странице появляется сообщение о том, что таймер удален, но золото не добавлено и новый таймер не запущен. Вам нужно нажать кнопку еще раз, чтобы запустить новый таймер и добавить немного золота.

Я думаю, что я выделил проблему для этого блока здесь:

                if ($ended == true) {

                    //addCoinsToUser($pdo, $user['id'], 10);
                    //startTimer($pdo, $user['id']);
                    echo 'You gained some coins.';

                } else {

                    echo startTimer($pdo, $user['id']);

                }

Истинная ветвь этого условия никогда не выполняется. Я попытался повторить $ended до этого, и он ничего не выводит. Я просматривал этот код снова и снова и не могу понять, почему он застревает в этом разделе - в основном, почему $ended всегда пуст?

Я прокомментировал, что должно произойти, если все это работает правильно - в основном он должен удалить таймер и запустить новый одним щелчком мыши.

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

Нажмите здесь для рабочего примера . (кнопка находится на странице указателя при входе в систему) Имя пользователя: пароль пользователя: пользователь

1 Ответ

0 голосов
/ 13 апреля 2019

Хорошо, я сам отвечу на этот вопрос, поскольку я только что выяснил, где я ошибался. В функции startTimer() я устанавливаю часовой пояс и зону по умолчанию - из-за перехода на летнее время это на час опережает время, установленное с помощью чего-то вроде $newTime = new DateTime(); в моей глобальной области видимости. Следовательно, оно никогда не будет оценено как истинное - если вы не ждете более часа между нажатиями кнопок.

Моим решением было установить часовой пояс по умолчанию в моей функции hasTimerEnded(). Вот так:

function hasTimerEnded($pdo, $user) {

    date_default_timezone_set('Europe/London');

    ...

}

Это на самом деле приводит к проблеме, когда вы можете получить 10 монет дважды подряд перед запуском таймера. Это было решено путем удаления существующего таймера перед запуском нового, когда эта надоедливая переменная $ended в конце концов получила значение true.

        if (isset($_GET['get_coins'])) {

            $hasTimer = userTimerExists($pdo, $user['id']);

            if ($hasTimer == true) {

                $ended = hasTimerEnded($pdo, $user['id']);

                if ($ended == true) {

                    $removeTimer = $pdo->prepare('delete from timers where user = :user');
                    $removeTimer->bindParam(':user', $user['id']);
                    $removeTimer->execute();

                    addCoinsToUser($pdo, $user['id'], 10);
                    startTimer($pdo, $user['id']);
                    echo '<br>You gained some coins.';

                } else {

                    echo startTimer($pdo, $user['id']);

                }

            } else {

                addCoinsToUser($pdo, $user['id'], 10);
                startTimer($pdo, $user['id']);
                echo '<br>coins coins coins';

            }

        }

        ?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...