0

我有一个脚本,用户可以在其中互相发送游戏内资金。

问题是,用户正在输入“give -99999 money to username ”,然后我的脚本从他们输入的用户那里获取 99999 并将其提供给他们。

所以这是我的脚本:

if(isset($_POST['usernameofmoney'])) 
{
    $resson= mysql_real_escape_string($_POST['usernameofmoney']);
    $resson2 = strip_tags($resson);

    $bannedusername= mysql_real_escape_string($_POST['money']);
    $bannedusername2 = strip_tags($bannedusername);

    $sql = "SELECT * FROM `users` WHERE `username` = '" . $_SESSION['username'] . "'";
    $result = mysql_query($sql) or die(mysql_error());
    $values = mysql_fetch_array($result);

    // We do this if they do no have enough coins
    if ( $values['money'] < $bannedusername2  ) {
        echo  "You Don't Have Enough Money Sorry";
        die;
    }

    if ( $values['money'] > $bannedusername2 ) {
        // Take the coins from the 1 users
        $gfgdgdfgds = mysql_query("UPDATE users SET money = money - ".$bannedusername2."
        WHERE username = '".$_SESSION['username']."'") or die(mysql_error()); 
        // Add the coins to the new user
        $gfgdgdfgdsf = mysql_query("UPDATE users SET money = money + ".$bannedusername2."
        WHERE username = '".$resson2."'") or die(mysql_error()); 

        echo "The Money Have Been Sent.";
    }
}

我知道我应该使用 PDO,今晚我将切换到 PDO。

这是我检查用户是否有钱可以发送。

 if ( $values['money'] < $bannedusername2  ) {
        echo  "You Don't Have Enough Money Sorry";
        die;
    }

$values['money'] 是不是有钱,而 $bannedusername2 是他们想给他们输入的钱。所以如果钱少于他们输入的钱,那么它将停止脚本,但他们正在输入 - 99999 和它让他们虽然..

4

1 回答 1

0

这可能不完全是您问题的答案,但是...

...如果我理解得很好,您的逻辑是:

  1. 通过发出SELECT请求检查是否有足够的钱可以发送,
  2. 如果是这样,通过执行两个连续的UPDATE查询来进行货币兑换。

当您单独测试应用程序时,这可能效果很好。但是,请记住,在生产环境中,您的数据库会有多个并发访问。

因此,如果假设用户 A 拥有 150 美元,同时给用户 C 和用户 D 100 美元,则可能出现以下情况:

  1. 检查用户 A 是否有超过 100 美元。是的。
  2. 检查用户 A 是否有超过 100 美元。是的。
  3. 由于 (1) 为真,给用户 B 100 美元。
  4. 由于 (2) 为真,给用户 B 100 美元。

哎呀。


另一种可能的失败是第一个成功UPDATE,但第二个失败(无论出于何种原因)。在这种情况下,一个用户的帐户将减少。钱就这样消失了……

又来了。


为了防止这些陷阱,您必须至少确保:

此外,而不是SELECT+ UPDATE,我会将您的第一个UPDATE请求重写为:

UPDATE users SET money = money - amount WHERE username = "User A"
AND money >= amount;

然后我会检查是否UPDATE影响了 0 或 1 行。前者的意思是“钱不够”。

于 2013-07-31T23:13:42.003 回答