-3

我试图防止用户刷新页面时多次提交表单。这是我的代码:

<form action="#" method="post">

                    <table border="0">
                        <tr>
                            <td id="tb-w_a"><p>Kategori</p></td>
                            <td>:</td>
                            <td>
                            <select name="kategori">
                            <?php
                            $query = "SELECT id, title FROM forum_kategorier";
                            $result = $mysqli->query($query);
                            while(list($id, $title) = $result->fetch_row())
                            {
                                echo "<option value=\"$id\">$title</option>";  
                            }
                            ?>
                            </select>
                            </td>
                        </tr>
                        <tr>
                            <td id="tb-w_a"><p>Title</p></td>
                            <td>:</td>
                            <td><input type="text" name="title"></td>
                        </tr>
                    </table>
                <textarea name="tekst_indhold" style="width:716px; height:170px;"></textarea><br />
                <input type="hidden" value="<?php echo $_SERVER['PHP_SELF'] ?>" name="return_page">
                <input type="submit" value="Opret indhold" name="godkendt">
            </form>
            <?php
            if ($stmt = $mysqli->prepare('INSERT INTO `forum_traede` (`kategori_id`, `bruger_id`, `tekst`, `dato`, `titel`) VALUES (?, ?, ?, NOW(), ?)')) { 
                $stmt->bind_param('ssss', $katgori_id, $bruger_id, $tekst, $titel);
                $katgori_id = $_POST["kategori"];
                $bruger_id = $_SESSION["user_id"];
                $tekst = $_POST["tekst_indhold"];
                $titel = $_POST["title"];

                $stmt->execute();
                $stmt->close();

                if (isset($_POST['return_page'])) {
                    $return_page = $_POST["return_page"];
                } else {
                    header('Location: http://xxxx.dk/bruger-forum-opret/');
                }

            } else {
                echo 'Der opstod en fejl i erklæringen: ' . $mysqli->error;
            }
        ?>

提交表单后,我收到以下错误:

警告:无法修改标头信息 - 第 78 行 /home/jesperbo/public_html/xxx.dk/xxx.php 中的标头(输出开始于 /home/jesperbo/public_html/xxx.dk/xxx.php:27)

这显示在页面顶部。

我还尝试将表单处理代码移动到单独的 .php 文件中,但随后出现此错误:

致命错误:在第 2 行的 /home/jesperbo/public_html/xxx.dk/bruger_forum-indhold-godkendt.php 中的非对象上调用成员函数 prepare()

提交表单后如何将浏览器重定向到新页面?

4

2 回答 2

2

简单的答案:将所有 PHP 代码放在所有 HTML 代码之前。

于 2012-06-07T18:58:13.583 回答
0

首先解决您的第二个问题:

致命错误:在第 2 行的 /home/jesperbo/public_html/xxx.dk/bruger_forum-indhold-godkendt.php 中的非对象上调用成员函数 prepare()

您的脚本中的代码似乎比您发布的要多;有几个对$mysqli变量的引用,我们在您的问题中没有看到其初始化。

如果仅将表单处理代码移动到单独的文件中,但不包含定义$mysqli变量的代码,则会遇到上述错误:您正在尝试调用$mysqli->prepare(),但$mysqli尚未定义。


现在解决第一个问题:

警告:无法修改标头信息 - 第 78 行 /home/jesperbo/public_html/xxx.dk/xxx.php 中的标头(输出开始于 /home/jesperbo/public_html/xxx.dk/xxx.php:27)

有几个问题导致了这个问题。我们将一次一个地解决它们。

1. 表单处理代码在表单未提交时执行。

至少,您应该在开始处理之前检查以确保表单已提交。考虑以下内容:

<form action="#" method="post">
  ...
</form>

<?php
  /* Check if the form was submitted. */
  if( $_POST ) {
    /* @todo Validate incoming values. */

    /* If all values are valid, insert into the database. */
    if ($stmt = $mysqli->prepare('INSERT INTO `forum_traede` (`kategori_id`, `bruger_id`, `tekst`, `dato`, `titel`) VALUES (?, ?, ?, NOW(), ?)')) {
      ...
    } else {
      ...
    }
  }

2. 即使表单已经提交,也会输出表单 HTML。

同样,如果表单尚未提交,您的脚本应该只输出表单 HTML。这就是阻止您的脚本正确重定向浏览器的原因。

您的脚本发送回浏览器的 HTTP 响应分为两部分:标头和正文。必须首先发送标头,这意味着一旦您的脚本输出某些内容,PHP 就会将其在该点的任何标头发送到浏览器,以便它可以发送正文。

由于您的脚本在设置标头之前尝试输出表单 HTML,location因此无法进行重定向(当 PHP 评估header()代码中的语句时,HTTP 标头已经发送到浏览器)。

要解决此问题,您需要将表单处理代码移至脚本顶部:

<?php
  /* Check if the form was submitted. */
  if( $_POST ) {
    /* @todo Validate incoming values. */

    /* If all values are valid, insert into the database. */
    if ($stmt = $mysqli->prepare('INSERT INTO `forum_traede` (`kategori_id`, `bruger_id`, `tekst`, `dato`, `titel`) VALUES (?, ?, ?, NOW(), ?)')) {
      ...
      $stmt->close();

      $return_page = (
        isset($_POST['return_page'])
          ? $_POST['return_page']
          : 'http://xxxx.dk/bruger-forum-opret/'
      );

      header(sprintf('Location: %s', $return_page));
      exit;
    } else {
      ...
    }
  }
?>

<!-- If we get to this point, either the form has not been submitted yet,
      or there is an error, so we should display the form HTML.
  -->
<form action="#" method="post">
  ...
</form>

另请注意,我在通话exit;后添加了一个。header()由于浏览器被重定向到新的 URL,因此不再显示表单。

$return_page另外,我对变量的用途有点不清楚。我认为目的是在表单中指定一旦处理完表单,浏览器将被重定向到的 URL。我更新了答案中的代码以反映这一点。

于 2012-06-07T20:13:19.027 回答