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

PHP删除数据库对象后Select选项不更新且报非对象属性提示

解决删除后选项不更新及Notice错误的问题

让我们一步步解决你的问题:

1. 先解决 "Trying to get property of non-object" 的Notice错误

这个错误的核心原因是:执行mysqli_multi_query后,数据库连接中残留了未处理的结果集,导致后续的$conn->query($sql)执行失败,返回false(不是对象),但你直接尝试访问$prove_result->num_rows,因此触发了Notice。

另外,你的代码存在SQL注入风险——直接将用户输入的$spmId拼接到SQL语句中,这是非常危险的,必须改用预处理语句来规避。

修改删除逻辑:

替换原来的multi_query代码,改用预处理语句分别执行两个DELETE操作,同时避免结果集阻塞:

if(isset($_POST['slettSpm'])){
    // 先验证并过滤输入,确保spmId是整数
    $spmId = filter_input(INPUT_POST, 'spmId', FILTER_VALIDATE_INT);
    if($spmId){
        // 删除alternativ表中的关联记录(预处理语句防注入)
        $stmt = $conn->prepare("DELETE FROM `alternativ` WHERE `SpormalId` = ?");
        $stmt->bind_param("i", $spmId); // "i"表示参数为整数类型
        $stmt->execute();
        $stmt->close();
        
        // 删除sporsmal表中的主记录
        $stmt = $conn->prepare("DELETE FROM `sporsmal` WHERE `SporsmalId` = ?");
        $stmt->bind_param("i", $spmId);
        $stmt->execute();
        $stmt->close();
    }

    // 关键操作:删除完成后重定向到当前页面
    // 既可以避免表单重复提交,又能强制刷新数据库数据
    header("Location: " . $_SERVER['PHP_SELF']);
    exit(); // 必须exit,防止后续代码继续执行
}

2. 解决删除后Select选项不更新的问题

当前代码在删除后直接在POST请求中生成页面,但由于浏览器缓存或连接状态异常,查询可能无法获取最新的数据库数据。使用上面的header("Location: ...")重定向,会触发一个GET请求重新加载页面,此时代码会重新查询数据库,自然会显示剩余的选项,不需要手动刷新。

3. 加固查询逻辑,避免潜在错误

在查询sporsmal列表时,先检查查询结果是否有效,防止再次出现non-object的Notice:

$sql = "SELECT * FROM sporsmal WHERE ProveId = $id";
$prove_result = $conn->query($sql);
// 先确认$prove_result是有效对象,再访问num_rows
if($prove_result && $prove_result->num_rows > 0) {
    while($row = $prove_result->fetch_assoc()){
        $sporsmal = htmlspecialchars($row["Sporsmal"]); // 转义输出,防止XSS攻击
        $sporsmalId = $row["SporsmalId"];
        echo "<option value='$sporsmalId'>$sporsmal</option>";
    }
} else {
    // 没有数据时给用户友好提示
    echo "<option value=''>Ingen spørsmål tilgjengelig</option>";
}

额外建议:

  • 始终验证和过滤用户输入:比如用filter_input确保spmId是整数,避免非法值传入数据库。
  • 开发环境开启错误提示:在代码开头加上error_reporting(E_ALL); ini_set('display_errors', 1);,方便快速定位问题。
  • 对输出内容进行转义:比如用htmlspecialchars处理用户输入的文本,防止XSS攻击。

修改后的完整关键代码片段:

<?php
// 开发环境开启错误提示
error_reporting(E_ALL);
ini_set('display_errors', 1);

session_start(); // 确保session已启动

if(isset($_POST['endreProve']) || isset($_POST['slettSpm'])){
    if(isset($_POST['slettSpm'])){
        $spmId = filter_input(INPUT_POST, 'spmId', FILTER_VALIDATE_INT);
        if($spmId){
            $stmt = $conn->prepare("DELETE FROM `alternativ` WHERE `SpormalId` = ?");
            $stmt->bind_param("i", $spmId);
            $stmt->execute();
            $stmt->close();
            
            $stmt = $conn->prepare("DELETE FROM `sporsmal` WHERE `SporsmalId` = ?");
            $stmt->bind_param("i", $spmId);
            $stmt->execute();
            $stmt->close();
        }
        header("Location: " . $_SERVER['PHP_SELF']);
        exit();
    }
    if(isset($_POST['endreProve'])){
        $id = $_POST['endreProve'];
        $id2 = explode('- ', $id);
        $_SESSION['proveId'] = $id2[1];
        header("Location: " . $_SERVER['PHP_SELF']);
        exit();
    }
}

// 确保proveId存在,避免空值导致SQL错误
$id = isset($_SESSION['proveId']) ? $_SESSION['proveId'] : '';
if(empty($id)){
    // 如果没有选中考试,跳转到选择页面
    header("Location: VelgProve.php");
    exit();
}
?>
<form style="padding-left: 30px; padding-top: 15px;" action="Rediger.php" method="POST">
    <div class='form-group row'>
        <div class='col-sm-12'>
            <h2><b> Prøve <?php echo $id ?> </b></h2>
            <label>Velg spørsmål:</label>
            <select name="spmId">
                <?php
                $sql = "SELECT * FROM sporsmal WHERE ProveId = $id";
                $prove_result = $conn->query($sql);
                if($prove_result && $prove_result->num_rows > 0) {
                    while($row = $prove_result->fetch_assoc()){
                        $sporsmal = htmlspecialchars($row["Sporsmal"]);
                        $sporsmalId = $row["SporsmalId"];
                        echo "<option value='$sporsmalId'>$sporsmal</option>";
                    }
                } else {
                    echo "<option value=''>Ingen spørsmål tilgjengelig</option>";
                }
                ?>
            </select>
            <input type='submit' class='btn btn-primary btn-sm' name='endreSpm' value='Endre'>
            <input type='submit' class='btn btn-danger btn-sm' name='slettSpm' value='Slett'><br/><br/>
            <!-- 剩余表单内容保持不变 -->
            <label><b>Legg til spørsmål</b></label><br/>
            <!-- ... 其他表单代码 ... -->
        </div>
    </div>
</form>

这样修改后,删除操作完成后会自动刷新页面,Select选项会显示最新的剩余内容,同时Notice错误也会消失,还大幅提升了代码的安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:48:51