阅读前需要注意的事项:
- 我知道代码不是那么出色。请不要评论我的旧作品;)
- 我知道 mysql_query 已被弃用。目前更新不在此问题的范围内
问题背景
我今天通过一个旧网站收到了一个有趣的错误报告,这引起了我的极大关注,因为我没想到会发生这个错误。
页面很简单。在原始负载上,在循环通过对数据库的 mysql 查询后会显示一个表。这些行中的每一行都显示一个链接:
url.com/items.php?use=XXX&confirm=0
XXX 与items table
数据库中项目的 ID 相关。确认 = 0 具有以下代码:
if(isset($_GET['use'])){
$id=@mysql_real_escape_string($_GET['use']);
if(isset($_GET['confirm'])){
$confirm=@mysql_real_escape_string($_GET['confirm']);
if($confirm==0){
// show a confirm button of YES / NO for them
// to click which has 1 for confirm
然后,用户可以单击“是”,将它们转移到:
url.com/items.php?use=XXX&confirm=1
然后代码else
从上面的代码转到执行以下检查的代码:
if($id<1){
echo "<p class='error-message'>An error has occurred.</p>";
print "<p class='center'><a href='http://www.url.com/items.php'>[Back]</a></p>";
include("inc/ftr.php");
exit();
}
if(empty($id)){
echo "<p class='error-message'>An error has occurred.</p>";
print "<p class='center'><a href='http://www.url.com/items.php'>[Back]</a></p>";
include("inc/ftr.php");
exit();
}
$quantity = 0;
$result=@mysql_query("SELECT * FROM inventory WHERE item_id=$id AND u_id=$user_id");
$num_rows=@mysql_num_rows($result);
$r=@mysql_fetch_array($result);
$quantity=$r['quantity'];
if($num_rows==0){
echo "<p class='error-message'>You do not own any of these.</p>";
print "<p class='center'><a href='http://www.url.com/items.php'>[Back]</a></p>";
include("inc/ftr.php");
exit();
}
if($quantity<1){
echo "<p class='error-message'>You don't have any of these left!</p>";
print "<p class='center'><a href='http://www.url.com/items.php'>[Back]</a></p>";
include("inc/ftr.php");
exit();
}
$result=@mysql_query("SELECT * FROM items WHERE id=$id");
$r=@mysql_fetch_array($result);
$type=$r['type'];
$item_name=$r['item_name'];
上面执行相关检查以确保 ID 存在,然后查询数据库以从库存中获取当前数量并检查它不低于 0。如果它低于 0,那么它会在此时阻止页面。
至此之后的代码从数据库中取出物品的数量,实现物品的“效果”。让我们假设执行了更新。
问题:
我在这里遇到的实际问题是,如果用户多次刷新页面,他们实际上可以update
执行查询,但他们实际上可以跳过对数量的检查。更新查询一遍又一遍地运行,但数量检查永远不会运行超过一次,因为没有错误消息。今天的一个例子是,当我的库存中有3 件物品时,我按了大约 100 次 f5。我设法让查询更新运行16 次,而没有显示任何错误消息。如果我然后等待几秒钟并再次按 f5,它将显示一条错误消息,说我没有任何这些项目。
以下解决方案不是一个选项,因为我不想浪费时间编码:
- 创建一个 ajax 调用以防止在处理所有查询之前多次提交。
- 实现 MVC 结构并将用户重定向到单独的页面,以防止多次提交
如果有人可以解释这个错误的原因(使用相关的阅读材料),或者甚至提供一个解决方案来解决它,那就太好了!谢谢!