简体   繁体   English

PHP 表单垃圾邮件预防

[英]PHP Form Spam Prevention

Please bear with me as I am a graphic designer with some coding knowledge, but not near as much as a developer.请耐心等待,因为我是一名具有一些编码知识的平面设计师,但不如开发人员多。 And after many hours of tinkering and asking Google, I've decided to ask y'all directly!经过数小时的修补和询问 Google,我决定直接询问你们!

I've been working on building a contact form for my website.我一直致力于为我的网站建立联系表格。 So far so good, except for one thing.到目前为止一切顺利,除了一件事。 I would like to add a simple spam prevention field.我想添加一个简单的垃圾邮件预防字段。

I've added a field "spamcheck" with the question 6+2=?我在问题 6+2=? but I do not know how to code the PHP to require that the value specifically be 8. As long as the other fields are correctly filled out, the form will submit regardless of the number entered here despite any attempt to mess with the code (thus why you will see my $spamcheck variable but the current coding only requires that it have a value like the rest of the fields).但我不知道如何对 PHP 进行编码以要求该值特别是 8。只要其他字段正确填写,无论在此处输入的数字如何,表单都会提交,尽管有任何试图弄乱代码的尝试(因此为什么您会看到我的 $spamcheck 变量,但当前编码只要求它具有与其余字段一样的值)。

I have included the PHP, the validation the PHP calls to, and the form.我已经包含了 PHP、PHP 调用的验证和表单。 Apologies if the form has some excess code;如果表单有一些多余的代码,请见谅; I have tried many different versions of PHP form tutorials to no avail.我尝试了许多不同版本的 PHP 表单教程都无济于事。

And of course, thank you very much for your help!当然,非常感谢您的帮助! :) :)

Here is the PHP code I have placed directly in the web page:这是我直接放在网页中的PHP代码:

<?php 
define("EMAIL", "email@gmail.com");

if(isset($_POST['submit'])) {

  include('validate.class.php');

  //assign post data to variables 
    $name = trim($_POST['name']);
    $email = trim($_POST['email']);
    $budget = trim($_POST['budget']);
    $deadline = trim($_POST['deadline']);
    $message = trim($_POST['message']);
    $spamcheck = trim($_POST['spamcheck']);

  //start validating our form
  $v = new validate();
  $v->validateStr($name, "name", 1, 50);
  $v->validateEmail($email, "email");
  $v->validateStr($budget, "budget");
  $v->validateStr($deadline, "deadline");
  $v->validateStr($message, "message", 1, 1000);
  $v->validateStr($spamcheck, "spamcheck");

  if(!$v->hasErrors()) {
       $from = "website.com"; //Site name
  // Change this to your email address you want to form sent to
  $to = "email@gmail.com"; 
  $subject = "Hello! Comment from " . $name . "";

  $message = "Message from " . $name . "
  Email: " . $email . " 
  Budget: " . $budget ."
  Deadline: " . $deadline ."
  Message: " . $message ."";
  mail($to,$subject,$message,$from);


    //grab the current url, append ?sent=yes to it and then redirect to that url
        $url = "http". ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
        header('Location: '.$url."?sent=yes");

    } else {
    //set the number of errors message
    $message_text = $v->errorNumMessage();       

    //store the errors list in a variable
    $errors = $v->displayErrors();

    //get the individual error messages
    $nameErr = $v->getError("name");
    $emailErr = $v->getError("email");
    $budgetErr = $v->getError("budget");
    $deadlineErr = $v->getError("deadline");
    $messageErr = $v->getError("message");
    $spamcheckErr = $v->getError("spamcheck");

  }//end error check
}// end isset
  ?>

This is the validate.class.php which it calls to:这是它调用的validate.class.php:

<?php
class validate {

  public $errors = array();

   public function validateStr($postVal, $postName, $min = 1, $max = 1000) {
    if(strlen($postVal) < intval($min)) {
      $this->setError($postName, ucfirst($postName)." is required.");
    } else if(strlen($postVal) > intval($max)) {
      $this->setError($postName, ucfirst($postName)." must be less than {$max} characters long.");
    }
  }// end validateStr

   public function validateEmail($emailVal, $emailName) {
    if(strlen($emailVal) <= 0) {
      $this->setError($emailName, "Please enter an Email Address");
    } else if (!preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/', $emailVal)) {
      $this->setError($emailName, "Please enter a Valid Email Address");
        }
  }// end validateEmail     

  private function setError($element, $message) {
    $this->errors[$element] = $message;
  }// end logError


  public function getError($elementName) {
    if($this->errors[$elementName]) {
      return $this->errors[$elementName];
    } else {
      return false;
    }
  }// end getError

  public function displayErrors() {
    $errorsList = "<ul class=\"errors\">\n";
    foreach($this->errors as $value) {
      $errorsList .= "<li>". $value . "</li>\n";
    }
    $errorsList .= "</ul>\n";
    return $errorsList;
  }// end displayErrors

  public function hasErrors() {
    if(count($this->errors) > 0) {
      return true;
    } else {
      return false;
    }
  }// end hasErrors

  public function errorNumMessage() {
    if(count($this->errors) > 1) {
            $message = "There was an error sending your message!\n";
        } else {
            $message = "There was an error sending your message!\n";
        }
    return $message;
  }// end hasErrors

}// end class
?>

And here is the form html/php:这是表单 html/php:

<span class="message"><?php echo $message_text; ?></span>
   <?php if(isset($_GET['sent'])): ?><h2>Your message has been sent</h2><?php endif; ?>
          <form role="form" method="post" action="webpage.php#contact">
            <div class="form-group">
              <input type="text" name="name" class="form-control" id="name" value="<?php echo htmlentities($name); ?>" placeholder="Full Name" required>
              <label for="exampleInputName"><i class="icon-tag"></i></label>
              <span class="errors"><?php echo $nameErr; ?></span>
              <div class="clearfix"></div>
            </div>
            <div class="form-group">
              <input type="email" name="email" class="form-control" id="email" value="<?php echo htmlentities($email); ?>" placeholder="Email" required>
              <label for="exampleInputEmail1"><i class="icon-inbox"></i></label>
              <span class="errors"><?php echo $emailErr; ?></span>
              <div class="clearfix"></div>
            </div>
            <div class="form-group">
              <input type="text" name="budget" class="form-control" id="budget" value="<?php echo htmlentities($budget); ?>" placeholder="Budget" required>
              <label for="exampleInputBudget1"><i class="icon-usd"></i></label>
              <span class="errors"><?php echo $budgetErr; ?></span>
              <div class="clearfix"></div>
            </div>
            <div class="form-group">
              <input type="text" name="deadline" class="form-control" id="deadline" value="<?php echo htmlentities($deadline); ?>" placeholder="Deadline" required>
              <label for="exampleInputDeadline"><i class="icon-calendar"></i></label>
              <span class="errors"><?php echo $deadlineErr; ?></span>
              <div class="clearfix"></div>
            </div>
            <div class="form-group textarea">
              <textarea rows="6" name="message" class="form-control" id="message" value="<?php echo htmlentities($message); ?>" placeholder="Write Message" required></textarea>
              <label for="exampleInputMessage"><i class="icon-pencil"></i></label>
              <span class="errors"><?php echo $messageErr; ?></span>
              <div class="clearfix"></div>
            </div>
            <div class="form-group">
              <input type="text" name="spamcheck" class="form-control" id="spamcheck" value="<?php echo htmlentities($spamcheck); ?>" placeholder="Spam check: 6+2=?" required>
              <label for="exampleInputSpamCheck"><i class="icon-lock"></i></label>
              <span class="errors"><?php echo $spamcheckErr; ?></span>
              <div class="clearfix"></div>
            </div>

            <button type="submit" id="submit" name="submit" value="submit" class="btn btn-large">Send Message</button>
          </form>

In the PHP script where you generate the form, you should save the correct answer to the question in a $_SESSION variable . 在生成表单的PHP脚本中,您应该在$_SESSION变量中保存问题的正确答案。

Then, in the PHP script that receives this form data, you should verify that what was submitted for that question matches the right answer in the $_SESSION variable. 然后,在接收此表单数据的PHP脚本中,您应该验证为该问题提交的内容是否与$_SESSION变量中的正确答案匹配。

There are a bunch of tutorials on how to use sessions in PHP. 有很多关于如何在PHP中使用会话的教程

Basically, it comes down to: 基本上,它归结为:

form.php form.php的

<?php
    session_start();
    $_SESSION['captcha_right_answer'] = somehow_generate_this();
?>

handler.php handler.php

<?php
    session_start();

    if ($_INPUT['captcha_answer'] != $_SESSION['captcha_right_answer']) {
        // Show "bad captcha" message, re-show form, whatever
    }
    else {
        // Captcha good - go on with life
    }
?>

Check this out as an alternative to a captcha. 其作为验证码的替代方案进行检查。 Then you could use your existing class to validate the field. 然后,您可以使用现有的类来验证该字段。 Say your hidden field has a name "fakeField" You could validate it with your validateSTR method via.. 假设您的隐藏字段名称为“fakeField”您可以通过validateSTR方法验证它。

$v->validateStr($fakeField, "fakeField",0,0);

Since your str check is checking > and < instead of >= and <= this will return true when the length is exactly 0. This might be an easier solution for someone with little code knowledge to integrate. 由于你的str检查是检查>和<而不是> =和<=当长度正好为0时,这将返回true。对于没有很少代码知识的人来说,这可能是一个更容易的解决方案。

Alternatively, if you're stuck on using a captcha of sort, and you know what you expect the value to be, you could add a method to check against the value you're expecting. 或者,如果你坚持使用排序验证码,并且你知道你期望值是什么,你可以添加一个方法来检查你期望的值。

The method: 方法:

public function validateCaptcha( $value,$name, $expectedValue) {
if(trim($value) != $expectedValue) {
  $this->setError($name, "Captcha Incorrect");
    }
}

then change the line of code 然后改变代码行

$v->validateStr($spamcheck, "spamcheck");

to

$v->validateCaptcha($spamcheck, "spamcheck", '6');

This isn't the best solution since there are so many powerful captchas out therebut it's easy to use. 这不是最好的解决方案,因为有很多强大的验证码,但它很容易使用。

Another simple method is to capture the time the page loads and compare it to the time the form was submitted.另一种简单的方法是捕获页面加载时间并将其与提交表单的时间进行比较。 If the difference was too short, exit the page.如果差异太小,退出页面。 spambots are quick;垃圾邮件程序很快; people are slow.人很慢。 Spambots may figure out various fields - even do math - but they are never going to wait around for more than a few seconds. Spambots 可能会找出各种领域——甚至做数学——但他们永远不会等待超过几秒钟。

It takes only two lines, one in the form:它只需要两行,其中一行是这样的:

<input name="timeloaded" type="hidden" value="<?php echo time();?>" />

and one in the form processing code:以及表单处理代码中的一个:

if(!(is_numeric($_POST['timeloaded'])) || time()-$_POST['timeloaded']<30) {header("Location: index.php"); exit;} 

This one is for a form that no human can fill out in less than 30 seconds.这是一个没有人可以在 30 秒内填写的表格。 Change that for the length of form you use.根据您使用的表格长度更改它。

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

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