【问题标题】:Posting Twice to MySql Database (On Occasion)两次发布到 MySql 数据库(偶尔)
【发布时间】:2019-10-10 20:08:30
【问题描述】:

我有一个将表单响应发布到 MySQL 数据库的脚本。但是,它有时会在每行之间以秒为单位向表格发布两次。

这里是处理脚本:

if (isset($_POST['SignIn']))
    {
        $Name = $_POST['Name'];
        $Sleep = $_POST['Sleep'];
        $Soreness = $_POST['Soreness'];
        $Fatigue = $_POST['Fatigue'];
        $Energy = $_POST['Energy'];
        $Stress = $_POST['Stress'];
        $Total = $Sleep + $Soreness + $Fatigue + $Energy + $Stress;
        $Comments = $_POST['Comments'];

        $sql = "
            INSERT INTO
                YDP_Wellbeing (Name, Sleep, Soreness, Fatigue, Energy, Stress, Total, Comments)
            VALUES
                ('$Name', $Sleep, $Soreness, $Fatigue, $Energy, $Stress, $Total, '$Comments')";

        if (mysqli_query($con, $sql))
        {
            $_SESSION['alert-type'] = 'success';
            $_SESSION['alert-head'] = 'Welcome!';
            $_SESSION['alert-body'] = 'Thank You <strong>' . $Name . '</strong> You\'re Response Has Been Submitted.';
            header("location: index.php");
        }
        else
        {
            echo "Failed: " . mysqli_error($con);
        }
    }

有时发一次,有时发两次,所以问题是间歇性出现的?

【问题讨论】:

  • 听起来代码有时会被调用两次。可能就像用户在等待片刻时再次单击按钮一样简单,或者可能重新加载处理表单帖子的页面。
  • 旁注:您的代码对 SQL 注入完全开放。这既是一个安全问题,也是常见的错误来源。您将想在此处了解 SQL 注入:php.net/manual/en/security.database.sql-injection.php 以及有关如何在此处防止它的信息和示例:stackoverflow.com/questions/60174/…
  • @David 是正确的。这里没有什么会插入两次,所以用户必须调用它两次。
  • 我总是在重定向后添加die(); 以防止脚本继续执行。见stackoverflow.com/questions/8665985/…
  • 您是否验证了重定向确实有效,或者它只是返回到同一页面并且它看起来就像它重定向了?

标签: php mysql session


【解决方案1】:

不一致行为的最可能原因是重定向后未能停止脚本。不添加die()exit(),脚本会继续执行。

由于您已将该部分包含在测试 POST 提交的 if 子句中,我假设如果它未通过测试,它将显示要提交的表单。由于重定向后脚本无法终止,它会再次打印表单(并且可能会或可能不会重定向)。

因此,可能发生的是您的用户正在提交表单;然后在提交后看到相同的表单

  1. 继续他的快乐之路,
  2. 重新提交表单,或
  3. 尝试按返回按钮并意外重新提交表单

【讨论】:

    【解决方案2】:

    您的代码容易受到以下攻击

    1.) sql 注入攻击,因为您将变量直接传递到 sql 查询中。我已经使用准备好的语句减轻了它

    2.) Html 注入和 XSS 攻击:您需要确保对表单输入进行清理。我用intval() 表示整数,strip_tags() 表示字符串,假设 你想去掉危险的html。

    3.) 会话固定攻击。我还使用session _regenerate_id() 消除了这种攻击

    这是你重新编写的代码

    <?php
    $servername = "localhost";
    $username = "db username goes here";
    $pass = "your db password here";
    $db_name = "your db name here";
    
    // Create connection
    $conn = new mysqli($servername, $username, $pass, $db_name);
    
    // Check connection
    if ($conn->connect_error) {
        echo "Connection to db failed";
    }
    
    if(isset($_POST['SignIn'])) {
    
            $Name = strip_tags($_POST['Name']);
            $Sleep = intval($_POST['Sleep']);
            $Soreness = intval($_POST['Soreness']);
            $Fatigue = intval($_POST['Fatigue']);
            $Energy = intval($_POST['Energy']);
            $Stress = intval($_POST['Stress']);
            $Total = $Sleep + $Soreness + $Fatigue + $Energy + $Stress;
            $Comments = strip_tags($_POST['Comments']);
    
    
    // prepare your data
    // i stands for integers and s stands for string
    $stmt = $conn->prepare("INSERT INTO YDP_Wellbeing (Name, Sleep, Soreness, Fatigue, Energy, Stress, Total, Comments) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("siiiiiis", $Name,$Sleep,$Soreness,$Fatigue,$Energy,$Stress,$Total,$Comments);
    $stmt->execute();
    
    if($stmt){
    echo "data inserted successfully";
    
    // create session
    session_start();
    // prevents session fixation attacks using session regenerate id
    session_regenerate_id();
    
    //
    $_SESSION['alert-type'] = 'success';
                $_SESSION['alert-head'] = 'Welcome!';
    
                $_SESSION['alert-body'] = 'Thank You <strong>' . $Name . '</strong> You\'re Response Has Been Submitted.';
    
                header("location: index.php");
    }else{
    echo "data insertion failed";
    }
    
    }
    
    $stmt->close();
    $conn->close();
    ?>
    

    【讨论】:

    • 为什么是strip_tags()intval()
    • 请阅读第 2 句。我刚刚添加了它,我说假设他想要剥离所有 html 元素。 Intval() 我需要确保他想要求和的那些值是整数。谢谢
    • 这是为了查看,不是为了防止查询时的sql注入。准备好的语句可以解决这个问题。
    • 为什么要重写?无论他们最后发生了什么,恕我直言,您的回答无法解决这个问题。
    • 虽然这对 OP 来说是非常有用的信息,但它实际上并不能回答问题。
    猜你喜欢
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 2021-10-03
    • 2015-07-10
    • 2012-05-17
    • 1970-01-01
    相关资源
    最近更新 更多