如何在另一个PHP文件中获取并确认表单输入数据
需求与问题
现有一个投注表单,提交至placebet.php后,需要先展示投注信息并提供确认/取消按钮,用户确认后再将数据存入数据库。同时原placebet.php代码存在逻辑错误,需要修正。
原HTML表单代码
<form action="placebet.php" method="post"> <div id="box" class="boxlit"> <div class="box" data-id="0">Myanmar - Vietnam<br>Home [1]<div class="crtTotal">4.30</div> <input type="hidden" name="kickoff[]" value="7/17/2022 10:00"> <input type="hidden" name="match[]" value="Myanmar - Vietnam"> <input type="hidden" name="result[]" value="Home [1]" readonly=""> <input type="hidden" name="value[]" value="4.30"></div> <div class="box" data-id="4">Thailand - Philippines<br>Draw [2]<div class="crtTotal">3.20</div> <input type="hidden" name="kickoff[]" value="7/17/2022 13:30"> <input type="hidden" name="match[]" value="Thailand - Philippines"> <input type="hidden" name="result[]" value="Draw [2]" readonly=""> <input type="hidden" name="value[]" value="3.20"></div> <div class="box" data-id="11">Botswana - Cameroon<br>Away [3]<div class="crtTotal">1.35</div> <input type="hidden" name="kickoff[]" value="7/17/2022 22:00"> <input type="hidden" name="match[]" value="Botswana - Cameroon"> <input type="hidden" name="result[]" value="Away [3]" readonly=""> <input type="hidden" name="value[]" value="1.35"></div></div><br> <input type="hidden" name="account[]" value="0818054386" readonly=""> <input type="hidden" name="balance[]" value="20" readonly=""> <input type="hidden" id="todds" name="todds[]" value="18.58" readonly=""> <input type="hidden" id="inp" name="payout[]" value="92.90" readonly=""> <div>Total Odds: <b id="ct1">18.58</b></div><br> <div>(N$)Stake: <input id="stake" type="number" name="stake[]" value="5"> NAD</div><br> <div>Payout: N$ <b id="payout">92.90</b></div> <input class="bet1" type="submit" name="submit" value="Bet"> </form>
原placebet.php代码(存在问题)
<?php /* Attempt MySQL server connection. Assuming you are running MySQL server with default setting (user 'root' with no password) */ $link = mysqli_connect("localhost", "root", "", "forms"); $dba = mysqli_connect("localhost","root","","login"); // Check connection if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } $error = false; //set the error status value $error_msg = ""; $back = mysqli_real_escape_string($link, $_REQUEST['kickoff'][0]); $total = count($back); // get the length of the match for($i=0;$i<$total;$i++){ // Escape user inputs for security $kickoff = mysqli_real_escape_string($link, $_REQUEST['kickoff'][$i]); $match = mysqli_real_escape_string($link, $_REQUEST['match'][$i]); $selection = mysqli_real_escape_string($link, $_REQUEST['result'][$i]); $odd = mysqli_real_escape_string($link, $_REQUEST['value'][$i]); $account = mysqli_real_escape_string($link, $_REQUEST['account'][0]); $stake = mysqli_real_escape_string($link, $_REQUEST['stake'][0]); $payout = mysqli_real_escape_string($link, $_REQUEST['payout'][0]); $todds = mysqli_real_escape_string($link, $_REQUEST['todds'][0]); $accabal = mysqli_real_escape_string($link, $_REQUEST['balance'][0]); //run sql query for every iteration $charge = mysqli_query($dba, "UPDATE users SET balance = $accabal- $stake WHERE username='".$_SESSION['username']."'") ; $_SESSION["balance"] = $accabal- $stake ; $date = date ('Ymd'); $create = mysqli_query($link,"CREATE TABLE R$date LIKE receipts") ; $insert = mysqli_query($link,"INSERT INTO `R$date`(`Match`, `Selection`, `Odd`,`Account`,`Stake Amount`,`Payout`,`Total Odds`) VALUES ('$match','$selection','$odd','$account','$stake','$payout','$todds')"); if(!$insert) { $error = true; $error_msg = $error_msg.mysqli_error($link); } //check your error status variable and show your output msg accordingly. if($error){ echo "Error :".$error_msg; }else{ header("location: index.php"); exit; } } mysqli_close($db); ?>
原代码核心问题
- 循环逻辑错误:通过字符串长度获取投注项数量,而非数组长度,导致循环次数错误。
- 会话未初始化:使用
$_SESSION但未调用session_start(),直接报错。 - SQL注入风险:直接拼接变量到SQL语句,未使用预处理。
- 重复操作:循环内重复创建表、更新余额,导致数据异常。
- 缺少确认环节:提交后直接写入数据库,无用户确认步骤。
解决方案:添加确认环节 + 修正代码
以下是完整的placebet.php修正版,实现"提交→确认→写入数据库"的流程:
<?php session_start(); // 必须启动会话 // 数据库连接 $link = mysqli_connect("localhost", "root", "", "forms"); $dba = mysqli_connect("localhost", "root", "", "login"); // 检查连接 if($link === false || $dba === false){ die("ERROR: 数据库连接失败. " . mysqli_connect_error()); } // 处理确认投注请求 if(isset($_POST['confirm_bet'])){ // 从会话取出临时存储的投注数据 $bet_data = $_SESSION['bet_data']; $kickoffs = $bet_data['kickoff']; $matches = $bet_data['match']; $results = $bet_data['result']; $values = $bet_data['value']; $account = $bet_data['account'][0]; $stake = $bet_data['stake'][0]; $payout = $bet_data['payout'][0]; $todds = $bet_data['todds'][0]; $accabal = $bet_data['balance'][0]; $username = $_SESSION['username']; $error = false; $error_msg = ""; // 更新用户余额(仅执行一次) $new_balance = $accabal - $stake; $update_stmt = mysqli_prepare($dba, "UPDATE users SET balance = ? WHERE username = ?"); mysqli_stmt_bind_param($update_stmt, "ds", $new_balance, $username); if(!mysqli_stmt_execute($update_stmt)){ $error = true; $error_msg .= "余额更新失败: " . mysqli_error($dba) . "<br>"; } else { $_SESSION["balance"] = $new_balance; } mysqli_stmt_close($update_stmt); // 创建当日收据表(不存在时才创建) $date = date('Ymd'); $table_name = "R$date"; $check_table = mysqli_query($link, "SHOW TABLES LIKE '$table_name'"); if(mysqli_num_rows($check_table) == 0){ if(!mysqli_query($link, "CREATE TABLE $table_name LIKE receipts")){ $error = true; $error_msg .= "创建表失败: " . mysqli_error($link) . "<br>"; } } // 插入每条投注记录 if(!$error){ $insert_stmt = mysqli_prepare($link, "INSERT INTO $table_name (`Match`, `Selection`, `Odd`,`Account`,`Stake Amount`,`Payout`,`Total Odds`) VALUES (?, ?, ?, ?, ?, ?, ?)"); foreach($matches as $index => $match){ $result = $results[$index]; $odd = $values[$index]; mysqli_stmt_bind_param($insert_stmt, "ssssddd", $match, $result, $odd, $account, $stake, $payout, $todds); if(!mysqli_stmt_execute($insert_stmt)){ $error = true; $error_msg .= "插入记录失败: " . mysqli_error($link) . "<br>"; break; } } mysqli_stmt_close($insert_stmt); } // 处理结果 if($error){ echo "<div style='color:red;'>错误: $error_msg</div>"; echo "<a href='index.php'>返回首页</a>"; } else { unset($_SESSION['bet_data']); // 清除临时数据 header("location: index.php?success=1"); exit; } // 处理取消投注请求 } elseif(isset($_POST['cancel_bet'])){ unset($_SESSION['bet_data']); header("location: index.php"); exit; // 首次提交表单,展示确认页面 } else { // 验证数据完整性 if(!isset($_POST['kickoff'], $_POST['match'], $_POST['result'], $_POST['value'], $_POST['account'], $_POST['stake'], $_POST['payout'], $_POST['todds'], $_POST['balance'])){ die("ERROR: 投注数据不完整"); } // 存储投注数据到会话 $_SESSION['bet_data'] = $_POST; // 提取数据用于展示 $kickoffs = $_POST['kickoff']; $matches = $_POST['match']; $results = $_POST['result']; $values = $_POST['value']; $account = $_POST['account'][0]; $stake = $_POST['stake'][0]; $payout = $_POST['payout'][0]; $todds = $_POST['todds'][0]; $accabal = $_POST['balance'][0]; ?> <!DOCTYPE html> <html> <head> <title>确认投注</title> <style> .bet-item { margin: 10px 0; padding: 10px; border: 1px solid #ddd; } .summary { margin: 20px 0; padding: 15px; background: #f5f5f5; } .btn { padding: 8px 16px; margin-right: 10px; cursor: pointer; border: none; border-radius: 4px; } .confirm-btn { background: #2ecc71; color: white; } .cancel-btn { background: #e74c3c; color: white; } </style> </head> <body> <h2>确认您的投注信息</h2> <div class="bet-list"> <?php foreach($matches as $index => $match): ?> <div class="bet-item"> <h4><?php echo htmlspecialchars($match); ?></h4> <p>投注选项: <?php echo htmlspecialchars($results[$index]); ?></p> <p>赔率: <?php echo htmlspecialchars($values[$index]); ?></p> <p>开赛时间: <?php echo htmlspecialchars($kickoffs[$index]); ?></p> </div> <?php endforeach; ?> </div> <div class="summary"> <p>账户: <?php echo htmlspecialchars($account); ?></p> <p>当前余额: N$ <?php echo htmlspecialchars($accabal); ?></p> <p>投注金额: N$ <?php echo htmlspecialchars($stake); ?></p> <p>总赔率: <?php echo htmlspecialchars($todds); ?></p> <p>预计派彩: N$ <?php echo htmlspecialchars($payout); ?></p> </div> <form method="post"> <button type="submit" name="confirm_bet" class="btn confirm-btn">确认投注</button> <button type="submit" name="cancel_bet" class="btn cancel-btn">取消投注</button> </form> </body> </html> <?php } // 关闭数据库连接 mysqli_close($link); mysqli_close($dba); ?>
关键改进
- 确认流程:首次提交后展示投注详情,用户确认后才执行数据库操作。
- 会话管理:用会话临时存储投注数据,避免重复提交。
- 安全防护:使用预处理语句防止SQL注入,
htmlspecialchars()防止XSS攻击。 - 逻辑修正:余额更新、表创建仅执行一次,循环仅处理投注记录插入。
- 错误处理:完善的错误提示,便于排查问题。
内容的提问来源于stack exchange,提问作者Nambuli89
相关产品推荐
相关产品推荐

