简体   繁体   English

使用会话存储针对PHP联系人表格的反垃圾邮件查询的答案

[英]Using Sessions to Store Answer to Anti-Spam Query for PHP Contact Form

I need help with a contact form for my website. 我需要网站联系表格方面的帮助。 I'll begin by explaining how my form is set up. 我将首先解释如何设置表单。 My website has a single page ( index.php ) with three sections. 我的网站只有一个页面( index.php ),其中包含三个部分。 The last one is "Contact Us" and it has a form where users are supposed to input their name, email address and a message. 最后一个是“联系我们”,它具有一种表格,用户可以在其中输入自己的姓名,电子邮件地址和消息。

My contact form worked ok, but it needed some security against spam bots. 我的联系表工作正常,但是需要针对垃圾邮件机器人的一些安全保护。 So I decided to add a simple anti-spam question, eg, "2 + 2." 因此,我决定添加一个简单的反垃圾邮件问题,例如“ 2 + 2”。 I wanted this question to be different each time and that's what's giving me problems. 我希望这个问题每次都不同,这就是给我带来问题的原因。 I'd really appreciate if you could point me in the right direction to solve this! 如果您能指出正确的方向解决此问题,我将不胜感激!

Here's the code I'm using. 这是我正在使用的代码。 I'll explain it below. 我会在下面解释。

<a name="contact"><h2>Contact Us</h2></a>
<?php
$operation = mt_rand(0, 2);
switch ($operation) {
    case 0:
        $r1    = mt_rand(0, 50);
        $r2    = mt_rand(0, 50);
        $r3    = $r1 + $r2;
        $query = "How much is $r1 + $r2?";
        break;
    case 1:
        $r1 = mt_rand(0, 50);
        do {
            $r2 = mt_rand(0, 50);
        } while ($r2 >= $r1);
        $r3        = $r1 - $r2;
        $query = "How much is $r1 - $r2?";
        break;
    case 2:
        $r1    = mt_rand(0, 10);
        $r2    = mt_rand(0, 10);
        $r3    = $r1 * $r2;
        $query = "How much is $r1 × $r2?";
        break;
}
if (isset($_POST["name"]) && isset($_POST["email"]) && isset($_POST["human"]) && isset($_POST["message"])) {
    $name    = spam_check('name');
    $from    = spam_check('email');
    $subject = empty($_POST['subject']) ? "Contact Form Message" : spam_check('subject');
    $human   = spam_check('human');
    $message = "<!DOCTYPE HTML><html><body><p>";
    $message .= "<strong>Name:</strong> " . $name . "<br>";
    $message .= "<strong>Email:</strong> <a href=\"mailto:" . $from . "\">" . $from . "</a></p>";
    $message .= "<p><strong>Message:</strong><br>" . spam_check('message') . "</p>";
    $message .= "</body></html>";
    $to      = "hello@example.com";
    $headers = "From: Me<hello@example.com>\nReply-To:" . $name . "<" . $from . ">\n";
    $headers .= "Mime-Version: 1.0\n";
    $headers .= "Content-Type: text/html; charset=UTF-8";
    if ($_POST['submit']) {
        if (!strcmp($human, $_SESSION['human'])) {
            if (mail($to, $subject, $message, $headers)) {
                echo "<p class=\"success\">Thanks for contacting us.</p>";
            } else {
                echo "<p class=\"failure\">Something went wrong, please try again!</p>";
            }
            unset($_SESSION['query']);
            unset($_SESSION['human']);
        } else {
            echo "<p class=\"warning\">You did not answer our anti-spam question. Do you need <a href=\"http://www.google.com/search?q=" . urlencode($_SESSION['query']) . "&amp;hl=en\">help</a>?</p>";
        }
    } else {
        echo "<p class=\"failure\">Something went wrong, please try again!</p>";
    }
}
if (!isset($_SESSION['human'])) {
    $_SESSION['query'] = $query;
    $_SESSION['human'] = "$r3";
} ?>
<form action="#contact" method="post">
    <input type="text" name="name" placeholder="Name" title="Name" required>
    <input type="email" name="email" placeholder="Email" title="Email" required>
    <input type="text" name="subject" placeholder="Subject" title="Subject">
    <input type="text" name="human" placeholder="<?php echo $query; ?>" title="<?php echo $query; ?>" required>
    <textarea name="message" placeholder="Write your message here&hellip;" title="Message" rows="10" cols="40" required></textarea>
    <input type="submit" name="submit" value="Send">
</form>

Here's the explanation of what I'm trying to achieve with the code above: first I generate one random number to decide if the question's going to be an addition, a subtraction or a multiplication. 这是我要通过上面的代码实现的目的的解释:首先,我生成一个随机数来确定问题是加,减还是乘。 If I get: 如果我有:

  • 0 , I generate two random numbers below 50 and add them. 0 ,我生成两个低于50的随机数,并将它们相加。
  • 1 , I generate two random numbers below 50 and subtract them (note: second number must not be greater than the first one to prevent negative results). 1 ,我生成两个小于50的随机数,然后将它们相减(注意:第二个数不得大于第一个,以免产生负面结果)。
  • 2 , I generate two random numbers below 10 and multiply them. 2 ,我生成两个低于10的随机数并将它们相乘。

The question's result is stored in $r3 and the question itself is stored in $query . 问题的结果存储在$r3 ,问题本身存储在$query

Next, I check if the user has submitted the form. 接下来,我检查用户是否已提交表单。 If they have, I extract their input using a function named spam_check . 如果有,我将使用名为spam_check的函数提取输入。 spam_check is supposed to stop header injection. spam_check应该停止标头注入。 It seems to work, although I haven't tested it thoroughly. 尽管我尚未对它进行彻底的测试,但这似乎可行。 Once I have extracted the values of each field, I start to construct the email's body and the headers. 提取每个字段的值后,我便开始构建电子邮件的正文和标头。 This works too. 这也可以。 Hold on we're about to get to the problem. 等等,我们将要解决这个问题。

The next step is to check if the user's answer to the anti-spam question ( $human ) matches the value of $r3 . 下一步是检查用户对反垃圾邮件问题( $human )的答案是否与$r3的值匹配。 This is the part that I can't get to work. 这是我无法工作的部分。 I used to have a simple check: $human == $r3 , but I soon realized it wasn't going to work because once you submit the form, the page reloads and $r3 becomes a new number. 我曾经做过一个简单的检查: $human == $r3 ,但是我很快意识到这是行不通的,因为一旦提交表单,页面就会重新加载并且$r3变成一个新的数字。 So I decided that maybe sessions were the way to go out. 因此,我认为可能是参加会议的方式。

In the last lines, the value of $r3 is stored in $_SESSION['human'] if $_SESSION['human'] is unset (eg, the first time the page is loaded). 在最后几行中,如果未设置$_SESSION['human'] (例如,第一次加载页面),则$r3的值将存储在$_SESSION['human'] To determine if the user answered correctly I use !strcmp($human, $_SESSION['human']) , but it doesn't work because $_SESSION['human'] does not store the value! 要确定用户是否正确回答,我使用!strcmp($human, $_SESSION['human']) ,但是它不起作用,因为$_SESSION['human']不存储该值!

It looks like once you submit the form, the session is somehow lost and the stored values are reset. 提交表单后,会话似乎丢失了,存储的值被重置了。 How can I store and preserve $r3 's value? 如何存储和保存$r3的值?

I've already checked if sessions are enabled in my server and I've also found the temporary session files (eg, query|s:20:"How much is 19 - 12?";human|s:1:"7"; ), so I don't where else to look for solutions. 我已经检查了服务器中是否启用了会话,还找到了临时会话文件(例如, query|s:20:"How much is 19 - 12?";human|s:1:"7"; ),所以我不在其他地方寻找解决方案。

You probably need to run 您可能需要跑步

session_start();

in the beginning of your code. 在代码的开头。 See http://www.php.net/session_start for more info. 有关更多信息,请参见http://www.php.net/session_start Notice that you should put session_start() before any other output to the browser. 注意,应将session_start()放在浏览器的任何其他输出之前。

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

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