PHP Как проверить, можете ли вы себе это позволить? - PullRequest
2 голосов
/ 25 февраля 2010

У меня есть это:

    $scCost = $row["gpsc"];
    mysql_query("
        UPDATE member_profile 
        SET points = points-$scCost 
        WHERE user_id = '".mysql_real_escape_string($userid)."'
    ") or die(mysql_error());

Требуются баллы пользователя - scCost.

Как проверить, может ли пользователь себе это позволить или нет? Итак, если у пользователя 30, а $ scCost - 40 ..

Ответы [ 6 ]

5 голосов
/ 25 февраля 2010

Вы можете сделать это атомарно, добавив дополнительное условие к запросу и используя mysql_affected_rows():

$scCost = $row["gpsc"];
$user_id = mysql_real_escape_string($user_id);
$sql = <<<END
UPDATE member_profile
SET points = points - $scCost
WHERE user_id = $user_id
AND points >= $scCost
END;
mysql_query($sql);
if (mysql_affected_rows() > 0) {
  // they can afford it
}

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

Предупреждение: mysql_affected_rows() возвращает количество строк, которые были изменены .Это важно понимать.Если вы передадите 0 затрат в этот запрос, вы получите:

UPDATE member_profiles SET points = points - 0 ...

mysql_affected_rows() всегда вернет 0 в этом случае, потому что ни одна строка не была изменена.Поэтому, если значение 0 является допустимым случаем, вам нужно отфильтровать это и вообще не беспокоиться о выполнении запроса.

Также это хорошо работает, если вы обновляете одну строку, но становится немного сложнее, если вы хотитеизменить несколько строк одновременно.Тогда вы попадаете в такие вопросы, как:

  • Что если некоторые «строки» могут себе это позволить, а другие нет?
  • Хотите ли вы, чтобы все они потерпели неудачу?
  • КакВы сообщаете, какие из них не могли себе это позволить?
  • Как вы все это делаете атомно?

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

1 голос
/ 25 февраля 2010

Вы должны получить эти данные и проверить на стороне PHP, прежде чем делать какие-либо обновления. В PHP вы должны проверить, не меньше ли это значение, чем 0 после минусовой операции.

0 голосов
/ 25 февраля 2010

Вы можете проверить сумму начальных баллов пользователей, выполнив SQL-запрос

$id = mysql_real_escape_string($userid);
$sql = "SELECT points FROM member_profile WHERE userid = $id";
$results = mysql_query($sql);
$row = mysql_fetch_array($results);
if($row['points'] > $scCost) {
// Update Row 
} else {
// Throw error 
}
0 голосов
/ 25 февраля 2010

добавьте секунду, где предложение "AND points> = $ scCost" и проверьте, сколько строк было изменено. Один ряд = они могли себе это позволить. Ноль строк они не могли.

$scCost = $row["gpsc"];
    mysql_query("
        UPDATE member_profile 
        SET points = points-$scCost 
        WHERE user_id = '".mysql_real_escape_string($userid)."' 
            AND points >= $scCost
    ") or die(mysql_error());

Jacob

0 голосов
/ 25 февраля 2010
SELECT points>=:cost AS canafford
FROM member_profile
WHERE user_id=:userid
0 голосов
/ 25 февраля 2010

Вам необходимо проверить, равно ли points или больше cost.

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