PHP Timer-函数在函数中正确求值,但在页面

时间:2019-04-12 22:32:32

标签: php sql datetime

我为标题含糊不清表示歉意,我不确定如何表达我的问题。

基本上,我正在构建浏览器游戏,并且用户拥有“硬币”或“金”。我有一个向该用户添加黄金的功能。我正在尝试设置一个动作计时器。计时器本身工作正常,我想出了关于倒计时的方法。

我现在要做的是在页面上添加一个按钮,单击该按钮后,会将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始终是用户ID,$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为何总是空的?

我已经注释掉了如果一切正常都应该发生的情况-基本上应该删除计时器并一键启动一个新计时器。

这是一个很长的问题,对不起,我知道我的代码可能有点冗长。

Click here for a working example。 (登录后,该按钮在索引页面上)用户名:用户密码:用户

1 个答案:

答案 0 :(得分:0)

好吧,我将自行回​​答这个问题,因为我刚刚弄清楚我要去哪里错了。在startTimer()函数中,我设置了默认时间和日期区域-由于夏令时,这比在我的全局范围内执行类似$newTime = new DateTime();的设置所设置的时间要早​​一小时。因此,它永远不会达到true-除非您在两次按钮单击之间等待了一个多小时。

我的解决方案是在我的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';

            }

        }

        ?>