简体   繁体   English

POST/REDIRECT/GET 在 PHP 联系表单中不起作用

[英]POST/REDIRECT/GET not working in PHP contact form

I am trying to configure a basic contact POST form with one checkbox input and server-side validation.我正在尝试使用一个复选框输入和服务器端验证配置一个基本的联系人 POST 表单。 This means the form must submit to itself, so a self-serving contact form.这意味着表单必须提交给自己,所以是一个自私的联系表单。 The problem I'm having is when refreshing the page, the form is submitted again.我遇到的问题是刷新页面时,表单再次提交。

I am using session data to store form validation as this form is an initial popup to which the user must tick and confirm to enter the page.我使用会话数据来存储表单验证,因为这个表单是一个初始弹出窗口,用户必须勾选并确认才能进入页面。 The page has two contact forms on it but I am showing one and I think the implementation should be the same for both (correct me if I'm wrong).该页面上有两个联系表格,但我展示了一个,我认为两者的实现应该相同(如果我错了,请纠正我)。 Once the user ticks the box and submits the form, the popup form will hide allowing the user to see the page.一旦用户勾选框并提交表单,弹出表单将隐藏以允许用户查看页面。

To solve this, I believe the POST/REDIRECT/GET design pattern should prevent this, however, I don't think my implementation is correct and I don't know what is wrong in my code.为了解决这个问题,我相信POST/REDIRECT/GET设计模式应该防止这种情况发生,但是,我认为我的实现不正确,我不知道我的代码有什么问题。

index.php code below: index.php 代码如下:

<!DOCTYPE html>
<html lang="en">
<?php
session_start();
include('form_process.php');
?>
<head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="assets/css/main.min.css" />
</head>
<body>
    <section id="selfCertOverlay" <?=$_SESSION['closeSelfCert']?>>
        <div class="blurOverlay">
            <form id="selfCert" method="post">
                <label for="self_cert">I have read and confirm the statement.
                    <input type="checkbox" name="self_cert" id="self_cert">
                    <span id="checkmark" class="<?= ($_SESSION['self_cert_checkbox_error']) ? 'inputError' : ''; ?>"></span>
                    <span class="error"><?= (isset($_SESSION["self_cert_error"])) ? $_SESSION["self_cert_error"] : ''; ?></span>
                </label>
                <input type="submit" name="submit_self_cert" value="Confirm & Proceed">
            </form>
        </div>
    </section>
</body>
</html>

form_process.php code below: form_process.php 代码如下:

<?php
$_SESSION["self_cert_error"] = "";
$_SESSION["self_cert_checkbox_error"] = false;

if (!isset($_POST["self_cert"])) {
    $_SESSION["self_cert_error"] = "Please read and accept the statement to proceed";
    $_SESSION["self_cert_checkbox_error"] = true;
} else {
    unset($_SESSION["self_cert_error"]);
    $message_body = '';
    unset($_POST['submit']);
    foreach ($_POST as $key => $value) {
        $keyOutput = str_replace('_', ' ', $key);
        $keyOutput = ucwords($keyOutput);
        $message_body .= "$keyOutput: $value\n";
    }
    $to = 'example@mailprovider.com';
    $subject = 'Email Subject';
    if (mail($to, $subject, $message_body)){
        $_SESSION["closeSelfCert"] = 'style="display: none;"';
        // Redirect to itself.
        header( "Location: {$_SERVER['REQUEST_URI']}", true, 303 );
        return;
    }
}
?>

The refresh button on the browser resends the last HTTP request that was sent by the client.浏览器上的刷新按钮重新发送客户端发送的最后一个 HTTP 请求。 This is why when you refresh the page, it re-submits the form.这就是为什么当您刷新页面时,它会重新提交表单。

The only way to get around this is to use the POST/REDIRECT method.解决这个问题的唯一方法是使用 POST/REDIRECT 方法。

To setup a POST/REDIRECT method, use an intermediate page to do the operations and then redirect to the original form afterwards.要设置 POST/REDIRECT 方法,请使用中间页面执行操作,然后重定向到原始表单。

For example: index.php --> the page with the form on - make sure the form has action="form_process.php" declared, so it will POST the data to the form_process.php script例如: index.php --> 带有表单的页面 - 确保表单已声明 action="form_process.php",因此它将数据 POST 到 form_process.php 脚本

form_process.php --> receives the form data and carries out your operations, then redirects back to the index.php page at the end. form_process.php --> 接收表单数据并执行您的操作,最后重定向回 index.php 页面。

So your final code should look something like the below;所以你的最终代码应该如下所示;

index.php索引.php

I have removed the include('form_process.php');我已经删除了include('form_process.php'); at the top在顶部

I have added action="form_process.php" to the <form> tag我已将action="form_process.php"添加到<form>标记

<!DOCTYPE html>
<html lang="en">
<?php
session_start();
?>
<head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="assets/css/main.min.css" />
</head>
<body>
    <section id="selfCertOverlay" <?=$_SESSION['closeSelfCert']?>>
        <div class="blurOverlay">
            <form id="selfCert" method="post" action="form_process.php">
                <label for="self_cert">I have read and confirm the statement.
                    <input type="checkbox" name="self_cert" id="self_cert">
                    <span id="checkmark" class="<?= ($_SESSION['self_cert_checkbox_error']) ? 'inputError' : ''; ?>"></span>
                    <span class="error"><?= (isset($_SESSION["self_cert_error"])) ? $_SESSION["self_cert_error"] : ''; ?></span>
                </label>
                <input type="submit" name="submit_self_cert" value="Confirm & Proceed">
            </form>
        </div>
    </section>
</body>
</html>

form_process.php form_process.php

I have added session_start();我添加了session_start(); at the top so you can access the $_SESSION data在顶部,以便您可以访问$_SESSION数据

I have added header( "Location: index.php", true, 303 );我添加了header( "Location: index.php", true, 303 ); within your first IF statement在你的第一个 IF 语句中

I have altered your header() routing which takes place after you send your email, so this redirects back to index.php我已经更改了在您发送电子邮件后发生的header()路由,因此这将重定向回 index.php

<?php
session_start();
$_SESSION["self_cert_error"] = "";
$_SESSION["self_cert_checkbox_error"] = false;

if (!isset($_POST["self_cert"])) {
    $_SESSION["self_cert_error"] = "Please read and accept the statement to proceed";
    $_SESSION["self_cert_checkbox_error"] = true;
    header( "Location: index.php", true, 303 );
    exit;
} else {
    unset($_SESSION["self_cert_error"]);
    $message_body = '';
    unset($_POST['submit']);
    foreach ($_POST as $key => $value) {
        $keyOutput = str_replace('_', ' ', $key);
        $keyOutput = ucwords($keyOutput);
        $message_body .= "$keyOutput: $value\n";
    }
    $to = 'example@mailprovider.com';
    $subject = 'Email Subject';
    if (mail($to, $subject, $message_body)){
        $_SESSION["closeSelfCert"] = 'style="display: none;"';
        // Redirect back to the form page.
        header( "Location: index.php", true, 303 );
        exit;
    }
}
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM