You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在另一个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);

?>

原代码核心问题

  1. 循环逻辑错误:通过字符串长度获取投注项数量,而非数组长度,导致循环次数错误。
  2. 会话未初始化:使用$_SESSION但未调用session_start(),直接报错。
  3. SQL注入风险:直接拼接变量到SQL语句,未使用预处理。
  4. 重复操作:循环内重复创建表、更新余额,导致数据异常。
  5. 缺少确认环节:提交后直接写入数据库,无用户确认步骤。

解决方案:添加确认环节 + 修正代码

以下是完整的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);
?>

关键改进

  1. 确认流程:首次提交后展示投注详情,用户确认后才执行数据库操作。
  2. 会话管理:用会话临时存储投注数据,避免重复提交。
  3. 安全防护:使用预处理语句防止SQL注入,htmlspecialchars()防止XSS攻击。
  4. 逻辑修正:余额更新、表创建仅执行一次,循环仅处理投注记录插入。
  5. 错误处理:完善的错误提示,便于排查问题。

内容的提问来源于stack exchange,提问作者Nambuli89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:33:29