采取以下方案:
项目成本= 30 用户资金= 25
如果用户没有足够的钱,表格将不会提交。
$error = false;
if($user_money < $item_cost){
//don't submit form
$error = true;
}
但那够了吗?即使没有足够的钱,用户是否可以绕过它并购买该物品?
做这样的事情会更好吗?
保持上述内容:
$error = false;
if($user_money < $item_cost){
//don t submit form
$error = true;
}else{
$myclass->purchaseItem($item_id, $user_id);
}
public function purchaseItem($item_id, $user_id) {
//do the validation here again something like. I don t know how to do the query exactly.
$q = $this->db->mysqli->prepare("INSERT INTO buys (bl bla blah) VALUES (?,?,?) IF ... user has enough points in user_points table");
}
希望这是有道理的,我不会投票。
答案 0 :(得分:0)
不应在服务器上验证数据两次。验证php端的数据将比数据库服务器更容易,更可靠。 有关验证输入数据的更多信息,您可以查看this。
答案 1 :(得分:0)
在数据库中,您可以使用触发器来检查约束。根据您的型号,您可能需要一个事务来防止错误地插入记录。
假设如下:
两张桌子:
如果用户购买了某些商品(明确买入,而不是购物车展示位置操作),则会在同一操作中更新钱包。
要执行此操作,您可以编写交易:有关如何使用,请参阅How to start and end transaction in mysqli?。
并使用2个语句:
UPDATE wallet SET amount=amount-{buyAmount} WHERE user=?;
INSERT INTO buys (amount,user,orderId) VALUES (?,?,?);
(当然,在准备好的声明中,buyAmount也是一个?)
或者您可以使用触发器。在插入购买表时,触发器必须锁定用户记录:
CREATE TRIGGER updateWallet() BEFORE INSERT ON buys
BEGIN
SET @updatedWalletAmount=0;
SELECT amount-NEW.buyAmount FROM wallet WHERE user=NEW.user FOR UPDATE;
IF(@updatedWalletAmount>0) THEN
UPDATE wallet SET amount=@updatedWalletAmount;
ELSE
SIGNAL SQLSTATE 'ERR0R'
SET
MESSAGE_TEXT = 'Not enough money',
MYSQL_ERRNO = 'USER-1';
END;
END;
错误必须在php中捕获。