我为标题含糊不清表示歉意,我不确定如何表达我的问题。
基本上,我正在构建浏览器游戏,并且用户拥有“硬币”或“金”。我有一个向该用户添加黄金的功能。我正在尝试设置一个动作计时器。计时器本身工作正常,我想出了关于倒计时的方法。
我现在要做的是在页面上添加一个按钮,单击该按钮后,会将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。 (登录后,该按钮在索引页面上)用户名:用户密码:用户
答案 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';
}
}
?>