【问题标题】:PHP Form Spam PreventionPHP 表单垃圾邮件预防
【发布时间】:2014-04-20 14:58:23
【问题描述】:

请多多包涵,因为我是一名具有一定编码知识的平面设计师,但不如开发人员多。经过数小时的修补和询问 Google,我决定直接询问你们!

我一直在为我的网站构建联系表单。到目前为止一切顺利,除了一件事。我想添加一个简单的垃圾邮件预防字段。

我添加了一个带有问题 6+2=? 的字段“spamcheck”。但我不知道如何对 PHP 进行编码以要求该值具体为 8。只要正确填写了其他字段,无论在此处输入的数字如何,表单都会提交,尽管任何尝试弄乱代码(因此为什么你会看到我的 $spamcheck 变量,但当前的编码只要求它具有与其他字段一样的值)。

我已经包含了 PHP、PHP 调用的验证以及表单。如果表单有一些多余的代码,我们深表歉意;我尝试了许多不同版本的 PHP 表单教程,但均无济于事。

当然,非常感谢您的帮助! :)

这是我直接放在网页中的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
  ?>

这是它调用的 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
?>

这里是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>

【问题讨论】:

    标签: php html forms validation spam-prevention


    【解决方案1】:

    在生成表单的 PHP 脚本中,您应该将问题的正确答案保存在 $_SESSION variable 中。

    然后,在接收此表单数据的 PHP 脚本中,您应该验证为该问题提交的内容是否与 $_SESSION 变量中的正确答案匹配。

    有一堆tutorials关于如何在 PHP 中使用会话。

    基本上归结为:

    form.php

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

    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
        }
    ?>
    

    【讨论】:

    • 感谢您的快速回复!我不得不承认我不确定如何写这个。我对 PHP 的了解足以编辑变量名称/错误消息。但不足以写出这样的东西。你介意告诉我怎么做吗?
    【解决方案2】:

    检查this 作为验证码的替代品。然后您可以使用现有的类来验证该字段。假设您的隐藏字段的名称为“fakeField”,您可以通过 validateSTR 方法对其进行验证..

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

    由于您的 str 检查正在检查 > 和 = 和

    或者,如果您坚持使用某种验证码,并且知道您期望的值是什么,您可以添加一个方法来检查您期望的值。

    方法:

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

    然后更改代码行

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

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

    这不是最好的解决方案,因为那里有很多强大的验证码,但它很容易使用。

    【讨论】:

    • 非常感谢!这对我来说绝对比 $_SESSION 更让人头疼,而且我能够让你的两个例子都起作用。我知道那里有更好的验证码,但这不是一个流量很大的网站,应该足以清除机器人。
    【解决方案3】:

    另一种简单的方法是捕获页面加载时间并将其与提交表单的时间进行比较。如果差值太短,退出页面。垃圾邮件程序很快;人们很慢。垃圾邮件机器人可能会计算出各个领域 - 甚至会做数学 - 但他们永远不会等待超过几秒钟。

    只需要两行,格式如下:

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

    还有一个表单处理代码:

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

    这是一个人类无法在 30 秒内填写的表格。根据您使用的表格长度更改它。

    【讨论】:

      猜你喜欢
      • 2017-06-08
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 2011-01-14
      相关资源
      最近更新 更多