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

PHP表单提交后保持选中数据库表显示及数据正常写入方案

问题说明

通过下拉表单选择数据库表展示的功能运行正常,但向选中表新增数据提交后,已选中展示的表消失,数据无法写入目标表。
实际运行流程:

  • 下拉菜单选择待展示表,点击选择按钮
  • 选中的表和对应表单正常加载展示
  • 表单填完数据点击提交
  • 下拉菜单恢复默认状态,已加载的表消失
  • 数据未写入目标表

预期运行流程:

  • 下拉菜单选择待展示表,点击选择按钮
  • 选中的表和对应表单正常加载展示
  • 表单填完数据点击提交
  • 选中的表保持展示,数据成功写入对应表

备注:contact_form.php仅适配messages表,不适配messages2表。


涉及代码文件

body.php(主页面)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Contact Form - PHP/MySQL Demo Code</title>
</head>
<style>
table, th, td {
  border:1px solid black;
}
</style>
<body>

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <div>
        <label for="dbselect">Select Table:</label><br>
        <select name="dbselect" id="dbselect">
            <option value=""><-- Choose Table --></option>
            <option value="messages">messages</option>
            <option value="messages2">messages2</option>
        </select>
    </div>
    <div>
        <button type="submit">Select</button>
    </div>   
</form>

<?php
    session_start();
    
    include 'get.php'; 
    $_SESSION["dbselect"] = filter_input(INPUT_POST, 'dbselect', FILTER_SANITIZE_STRING);                               
    if ($_SESSION["dbselect"] == "messages") {
        dbMessages("*");
        include 'Forms/contact_form.php';
    }
    if ($_SESSION["dbselect"] == "messages2") {
        dbMessages2("*");
    }                    
    
?>
</body>

get.php(表内容渲染输出)

<?php
function display_data($data) {
    $output = "<table>";
    foreach($data as $key => $var) {
        //$output .= '<tr>';
        if($key===0) {
            $output .= '<tr>';
            foreach($var as $col => $val) {
                $output .= "<td>" . $col . '</td>';
            }
            $output .= '</tr>';
            foreach($var as $col => $val) {
                $output .= '<td>' . $val . '</td>';
            }
            $output .= '</tr>';
        }
        else {
            $output .= '<tr>';
            foreach($var as $col => $val) {
                $output .= '<td>' . $val . '</td>';
            }
            $output .= '</tr>';
        }
    }
    $output .= '</table>';
    echo $output;
}

function dbMessages($selector) {
    include 'db.php';
    $query = "SELECT $selector FROM messages";
    $res = mysqli_query($conn,$query);
    display_data($res);
}

function dbMessages2($selector) {
    include 'db.php';
    $query = "SELECT $selector FROM messages2";
    $res = mysqli_query($conn,$query);
    display_data($res);
}      
        

contact_form.php(新增数据表单)

<?php

include 'db.php';
if ((isset($_POST["Submit"])) && (!empty($_POST["txtName"])) && (!empty($_POST["txtPhone"])) && (!empty($_POST["txtEmail"])) && (!empty($_POST["txtMessage"]))) {
    $txtName = $_POST['txtName'];
    $txtEmail = $_POST['txtEmail'];
    $txtPhone = $_POST['txtPhone'];
    $txtMessage = $_POST['txtMessage'];
    $query = "insert into messages(ID, name, email, phone, message) values (NULL, 
                '$txtName', '$txtEmail', '$txtPhone', '$txtMessage')";
    
    $res = mysqli_query($conn , $query);
    
    mysqli_close($conn);
    unset($_POST);
    echo "<meta http-equiv='refresh' content='0'>";
}

echo '
<fieldset>
<legend>Contact Form</legend>
<form name="frmContact" method="post" action="index.php?send=1" target="_self">
<p>
<label for="Name">Name </label>
<input type="text" name="txtName" id="txtName" >
</p>
<p>
<label for="email">Email</label>
<input type="text" name="txtEmail" id="txtEmail">
</p>
<p>
<label for="phone">Phone</label>
<input type="text" name="txtPhone" id="txtPhone">
</p>
<p>
<label for="message">Message</label>
<textarea name="txtMessage" id="txtMessage"></textarea>
</p>
<p>&nbsp;</p>
<p>
<input type="submit" name="Submit" id="Submit" value="Submit">
</p>
</form>
</fieldset>
'
?>

问题原因
  • 会话赋值逻辑错误:body.php每次加载都会无条件用POST参数覆盖$_SESSION["dbselect"],提交新增表单时请求里没有dbselect参数,直接把会话中存储的选中表值覆盖为空,无法加载对应表内容。
  • 会话启动位置错误:session_start()放在HTML输出之后,会触发"headers already sent"错误,导致会话无法正常读写。
  • 表单提交地址错误:contact_form.php的表单action写死为index.php?send=1,但主页面文件是body.php,提交后请求发到错误路径,逻辑无法正常执行。
  • 重复引入数据库连接:多个函数重复include 'db.php',容易引发连接变量重复定义的错误。
  • SQL拼接风险:直接把用户输入拼接到INSERT语句中,没有转义特殊字符,既存在SQL注入风险,也容易因为输入内容包含特殊字符导致SQL执行失败。

修复方案

1. 修改body.php

把session_start()移到文件最开头,仅当POST请求中存在dbselect参数时才更新会话值,同时给下拉菜单增加选中状态保持。
修复后代码:

<?php session_start(); ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Contact Form - PHP/MySQL Demo Code</title>
</head>
<style>
table, th, td {
  border:1px solid black;
}
</style>
<body>

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post">
    <div>
        <label for="dbselect">Select Table:</label><br>
        <select name="dbselect" id="dbselect">
            <option value="" <?php echo (($_SESSION["dbselect"] ?? "") == "") ? "selected" : ""; ?>><-- Choose Table --></option>
            <option value="messages" <?php echo (($_SESSION["dbselect"] ?? "") == "messages") ? "selected" : ""; ?>>messages</option>
            <option value="messages2" <?php echo (($_SESSION["dbselect"] ?? "") == "messages2") ? "selected" : ""; ?>>messages2</option>
        </select>
    </div>
    <div>
        <button type="submit">Select</button>
    </div>   
</form>

<?php
    include 'get.php'; 
    // 仅当提交了表选择参数时才更新会话
    if (isset($_POST['dbselect'])) {
        $_SESSION["dbselect"] = filter_input(INPUT_POST, 'dbselect', FILTER_SANITIZE_STRING);
    }
    $currentTable = $_SESSION["dbselect"] ?? "";
    if ($currentTable == "messages") {
        dbMessages("*");
        include 'Forms/contact_form.php';
    }
    if ($currentTable == "messages2") {
        dbMessages2("*");
    }                    
?>
</body>

2. 修改get.php

把数据库连接文件的引入改为include_once,避免重复引入报错,同时给查询增加错误判断:

<?php
include_once 'db.php';
function display_data($data) {
    $output = "<table>";
    foreach($data as $key => $var) {
        if($key===0) {
            $output .= '<tr>';
            foreach($var as $col => $val) {
                $output .= "<td>" . $col . '</td>';
            }
            $output .= '</tr>';
            foreach($var as $col => $val) {
                $output .= '<td>' . $val . '</td>';
            }
            $output .= '</tr>';
        }
        else {
            $output .= '<tr>';
            foreach($var as $col => $val) {
                $output .= '<td>' . $val . '</td>';
            }
            $output .= '</tr>';
        }
    }
    $output .= '</table>';
    echo $output;
}

function dbMessages($selector) {
    global $conn;
    $query = "SELECT $selector FROM messages";
    $res = mysqli_query($conn,$query);
    if ($res) {
        display_data($res);
    }
}

function dbMessages2($selector) {
    global $conn;
    $query = "SELECT $selector FROM messages2";
    $res = mysqli_query($conn,$query);
    if ($res) {
        display_data($res);
    }
}      

3. 修改contact_form.php

修正表单提交地址,改用预处理语句执行INSERT避免SQL注入,提交后通过跳转重载页面避免重复提交:

<?php
global $conn;
if ((isset($_POST["Submit"])) && (!empty($_POST["txtName"])) && (!empty($_POST["txtPhone"])) && (!empty($_POST["txtEmail"])) && (!empty($_POST["txtMessage"]))) {
    $txtName = trim($_POST['txtName']);
    $txtEmail = trim($_POST['txtEmail']);
    $txtPhone = trim($_POST['txtPhone']);
    $txtMessage = trim($_POST['txtMessage']);
    // 用预处理语句防止注入
    $stmt = mysqli_prepare($conn, "insert into messages(ID, name, email, phone, message) values (NULL, ?, ?, ?, ?)");
    mysqli_stmt_bind_param($stmt, "ssss", $txtName, $txtEmail, $txtPhone, $txtMessage);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_close($stmt);
    // 提交后跳转到当前页,避免重复提交
    header("Location: ".$_SERVER['PHP_SELF']);
    exit;
}
?>
<fieldset>
<legend>Contact Form</legend>
<form name="frmContact" method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" target="_self">
<p>
<label for="Name">Name </label>
<input type="text" name="txtName" id="txtName" >
</p>
<p>
<label for="email">Email</label>
<input type="text" name="txtEmail" id="txtEmail">
</p>
<p>
<label for="phone">Phone</label>
<input type="text" name="txtPhone" id="txtPhone">
</p>
<p>
<label for="message">Message</label>
<textarea name="txtMessage" id="txtMessage"></textarea>
</p>
<p>&nbsp;</p>
<p>
<input type="submit" name="Submit" id="Submit" value="Submit">
</p>
</form>
</fieldset>

修改完成后,提交新增数据时会保留当前选中的表状态,数据可正常写入,页面不会重置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:54:29