带有字段验证的简单联系人表单

时间:2016-08-23 作者:user53340

我希望创建一个非常简单的联系人,我可以用一个短代码输出。我有以下代码,但它似乎无法正确验证,甚至允许您在不输入任何详细信息的情况下提交表单。有没有人能解释一下如何验证表格。我还想添加一个蜜罐陷阱,因为这些陷阱比imo捕获的要好,但我对PHP非常陌生。任何帮助都会很好,谢谢。

    function html_form_code() {
    echo \'<form action="\' . esc_url( $_SERVER[\'REQUEST_URI\'] ) . \'" method="post">\';
    echo \'<p>\';
    echo \'Your Name (required) <br />\';
    echo \'<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="\' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : \'\' ) . \'" size="40" />\';
    echo \'</p>\';
    echo \'<p>\';
    echo \'Your Email (required) <br />\';
    echo \'<input type="email" name="cf-email" value="\' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : \'\' ) . \'" size="40" />\';
    echo \'</p>\';
    echo \'<p>\';
    echo \'Your Message (required) <br />\';
    echo \'<textarea rows="10" cols="35" name="cf-message">\' . ( isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : \'\' ) . \'</textarea>\';
    echo \'</p>\';
    echo \'<input type="text" name="content" id="content" value="" class="hpot" />\';
    echo \'<p><input type="submit" name="cf-submitted" value="Send"/></p>\';
    echo \'</form>\';
}

function deliver_mail() {

  $errors = new WP_Error();
if ( isset( $_POST[ \'content\' ] ) && $_POST[ \'content\' ] !== \'\' ) {
  $errors->add( \'cheater\', \'Sorry, this field should not be filled. Are you trying to cheat?\' );
}
if ( isset( $_POST[ \'cf-name\' ] ) && $_POST[ \'cf-name\' ] == \'\' ) {
  $errors->add(\'error\', \'Please fill in a valid name.\' );
}

if ( isset( $_POST[ \'cf-email\' ] ) && $_POST[ \'cf-email\' ] == \'\' ) {
  $errors->add(\'error\', \'Please fill in a valid email.\' );
}

if ( isset( $_POST[ \'cf-message\' ] ) && $_POST[ \'cf-message\' ] == \'\' ) {
  $errors->add(\'error\', \'Please fill in a valid message.\' );
}

if ( empty( $errors->errors ) ){
  deliver_mail();
}
else {
  echo \'Please fill the required fields\';
}


    // if the submit button is clicked, send the email
    if ( isset( $_POST[\'cf-submitted\'] ) ) {

        // sanitize form values
        $name    = sanitize_text_field( $_POST["cf-name"] );
        $email   = sanitize_email( $_POST["cf-email"] );
        $message = esc_textarea( $_POST["cf-message"] );

        // get the administrator\'s email address
        $to = get_option( \'admin_email\' );

        $headers = "From: $name <$email>" . "\\r\\n";

        // If email has been process for sending, display a success message
        if ( wp_mail( $to, $message, $headers ) ) {
            echo \'<div class=cf-success>\';
            echo \'<p>Thank you for contacting us \'. $name .\', a member of our team will be in touch with you shortly.</p>\';
            echo \'</div>\';
        } else {
            echo \'<div class=cf-error>\';
            echo \'<p>An unexpected error occurred</p>\';
            echo \'</div>\';
        }
    }
}

function cf_contact_form() {
    ob_start();
    deliver_mail();
    html_form_code();

    return ob_get_clean();
}

add_shortcode( \'contact_form\', \'cf_contact_form\' );
那么会像上面那样吗?谢谢

我在尝试运行字段检查时也收到此错误。

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in /Applications/MAMP/htdocs/centenary-framework/wp-content/themes/cent_framework/assets/inc/core/contact-form.php on line 147

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in /Applications/MAMP/htdocs/centenary-framework/wp-includes/load.php on line 671
我不知道这意味着什么=(

编辑

这些问题现已修复。我正在粘贴下面的工作代码,希望它能在将来帮助别人。非常感谢所有帮助过我的人!!

// Form markup
 function html_form_code()
 {
     ?>

 <form action="<?php esc_url($_SERVER[\'REQUEST_URI\']);
     ?>" method="post">
   <p>Your Name (required)<br />
     <input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="<?php isset($_POST[\'cf-name\']) ? esc_attr($_POST[\'cf-name\']) : \'\';
     ?>" size="40" />
   </p>
   <p>Your Email (required)<br />
     <input type="email" name="cf-email" value="<?php isset($_POST[\'cf-email\']) ? esc_attr($_POST[\'cf-email\']) : \'\';
     ?>" size="40" />
   </p>
   <p>Your Message (required)<br />
     <textarea rows="10" cols="35" name="cf-message"><?php isset($_POST[\'cf-message\']) ? esc_attr($_POST[\'cf-message\']) : \'\';
     ?></textarea>
   </p>
   <p><input type="submit" name="cf-submitted" value="Send"/></p>
 </form>

 <?php

 }

// Form validation
 function my_validate_form()
 {
     $errors = new WP_Error();

     if (isset($_POST[ \'content\' ]) && $_POST[ \'content\' ] !== \'\') {
         $errors->add(\'cheater\', \'Sorry, this field should not be filled. Are you trying to cheat?\');
     }

     if (isset($_POST[ \'cf-name\' ]) && $_POST[ \'cf-name\' ] == \'\') {
         $errors->add(\'name_error\', \'Please fill in a valid name.\');
     }

     if (isset($_POST[ \'cf-email\' ]) && $_POST[ \'cf-email\' ] == \'\') {
         $errors->add(\'email_error\', \'Please fill in a valid email.\');
     }

     if (isset($_POST[ \'cf-message\' ]) && $_POST[ \'cf-message\' ] == \'\') {
         $errors->add(\'message_error\', \'Please fill in a valid message.\');
     }

     return $errors;
 }

// Form delivery
 function deliver_mail($args = array())
 {

  // This $default array is a way to initialize some default values that will be overwritten by our $args array.
  // We could add more keys as we see fit and it\'s a nice way to see what parameter we are using in our function.
  // It will only be overwritten with the values of our $args array if the keys are present in $args.
  // This uses WP wp_parse_args() function.
  $defaults = array(
    \'name\' => \'\',
    \'email\' => \'\',
    \'message\' => \'\',
    \'to\' => get_option(\'admin_email\'), // get the administrator\'s email address
  );

     $args = wp_parse_args($args, $defaults);

     $headers = "From: {$args[\'name\']}  <{$args[\'email\']}>"."\\r\\n";

  // Send email returns true on success, false otherwise
  if (wp_mail($args[\'to\'], $args[\'message\'], $headers)) {
      return;
  } else {
      return false;
  }
 }

// Form sanitize
function my_sanitize_field($input)
{
    return trim(stripslashes(sanitize_text_field($input)));
}

// Form succsess message
function my_form_message()
{
    global $errors;
    if (is_wp_error($errors) && empty($errors->errors)) {
        echo \'<div class="cf-success">\';
        echo \'<p>Thank you for contacting us \'.$_POST[\'cf-name\'].\', a member of our team will be in touch with you shortly.</p>\';
        echo \'</div>\';

    //Empty $_POST because we already sent email
    $_POST = \'\';
    } else {
        if (is_wp_error($errors) && !empty($errors->errors)) {
            $error_messages = $errors->get_error_messages();
            foreach ($error_messages as $k => $message) {
                echo \'<div class="cf-error \'.$k.\'">\';
                echo \'<p>\'.$message.\'</p>\';
                echo \'</div>\';
            }
        }
    }
}

// Form shortcode
add_shortcode(\'contact_form\', \'cf_contact_form\');
function cf_contact_form()
{
    ob_start();

    my_form_message();
    html_form_code();

    return ob_get_clean();
}

// Error validation
add_action(\'init\', \'my_cf_form\');
function my_cf_form()
{
    if (isset($_POST[\'cf-submitted\'])) {
        global $errors;
        $errors = my_validate_form();
        if (empty($errors->errors)) {
            $args = array(
         \'name\' => my_sanitize_field($_POST[\'cf-name\']),
         \'email\' => my_sanitize_field($_POST[\'cf-email\']),
         \'message\' => my_sanitize_field($_POST[\'cf-message\']),
       );
            deliver_mail($args);
        } else {
            return $errors;
        }
    }
}

2 个回复
最合适的回答,由SO网友:bynicolas 整理而成

您没有任何验证机制。

你的逻辑应该是沿着这些思路

提交表单根据预期值检查提交的字段($\\u POST)

  • 如果一切正常,则发送;如果有不符合预期的情况,则记录错误(您可以使用WP\\u error())并重新生成显示错误消息的表单(可能会使用以前的“良好”值重新填充字段)
  • 我在这里看到的只是清理输入,但实际上并没有验证输入是否具有您期望的值(即有效的电子邮件、电话、姓名长度等)。

    无论字段是否具有预期值,都可以发送电子邮件。否则将输出错误ONLY 如果wp_mail() 如果实际字段是否具有验证值,则不会失败。

    要添加蜜罐,只需在表单中添加一个预期为空的隐藏字段。

    例如,在HTML中

    <input type="text" name="content" id="content" value="" class="hpot" />
    
    然后,当您验证表单输入时,您希望该字段为空。

    使用WP_Error 类,您可以向对象添加错误,以便以后使用它们通知用户或诸如此类的内容。

    $errors = new WP_Error();
    if ( isset( $_POST[ \'content\' ] ) && $_POST[ \'content\' ] !== \'\' ) {
      $errors->add( \'cheater\', \'Sorry, this field should not be filled. Are you trying to cheat?\' );
    }
    
    因此,上面的PHP检查是一种可以用来验证表单的方法。您只需添加一些if 具有表单期望值的语句(当然,这可以扩展为验证输入的函数)。然后,如果使用WP\\u Error类,通过在发现错误时添加到对象,只需在发送之前进行最后检查。

    if ( empty( $errors->errors ) ){
      deliver_mail();
    }
    else {
      // Here you can use your $_POST variable to repopulate the form with accepted 
      // form value (you would have to update your html_form_code() to accept an argument) 
      // or just reload the contact page displaying an error message.
    }
    

    EDIT

    好的,这里有一个更完整的例子

    CSS

    将其添加到css中,以便该字段实际上不会显示在浏览器中

    .hpot {
      display: none;
    }
    

    PHP

    下面是编写html函数的另一种方法,它更易于阅读

    function html_form_code() { ?>
    
    <form action="<?php esc_url( $_SERVER[\'REQUEST_URI\'] ); ?>" method="post">
      <p>Your Name (required)<br />
        <input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="<?php isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : \'\'; ?>" size="40" />
      </p>
      <p>Your Email (required)<br />
        <input type="email" name="cf-email" value="<?php isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : \'\'; ?>" size="40" />
      </p>
      <p>Your Message (required)<br />
        <textarea rows="10" cols="35" name="cf-message"><?php isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : \'\'; ?></textarea>
      </p>
      <p><input type="submit" name="cf-submitted" value="Send"/></p>
    </form>
    
    <?php } 
    
    deliver\\u mail功能不应侦听$_POST 不应进行消毒。另一方面,使用表单用户电子邮件作为发件人标头可能会导致某些ISP出现一些问题,因为电子邮件是从your 域,现在从您的域发送电子邮件,但在发件人地址中包含不匹配的域(可能被视为垃圾邮件)。在此处使用域中的地址(例如[email protected])并在电子邮件正文(在邮件中)中设置用户的电子邮件。您还可以将其设置为reply-to 字段以便于使用。

    function deliver_mail( $args = array() ) {
    
      // This $default array is a way to initialize some default values that will be overwritten by our $args array.
      // We could add more keys as we see fit and it\'s a nice way to see what parameter we are using in our function.
      // It will only be overwritten with the values of our $args array if the keys are present in $args.
      // This uses WP wp_parse_args() function.
      $defaults = array(
        \'name\'    => \'\',
        \'email\'   => \'\',
        \'message\' => \'\',
        \'to\'      => get_option( \'admin_email\' ), // get the administrator\'s email address
      );
    
      $args = wp_parse_args( $args, $defaults );
    
      $headers = "From: {$args[\'name\']} <{$args[\'email\']}>" . "\\r\\n";
    
      // Send email returns true on success, false otherwise
      if( wp_mail( $args[\'to\'], $args[\'message\'], $headers ) ) {
        return;
      }
      else {
        return false;
      }
    }
    
    您的验证功能

    function my_validate_form() {
    
      $errors = new WP_Error();
    
      if ( isset( $_POST[ \'content\' ] ) && $_POST[ \'content\' ] !== \'\' ) {
        $errors->add( \'cheater\', \'Sorry, this field should not be filled. Are you trying to cheat?\' );
      }
    
      if ( isset( $_POST[ \'cf-name\' ] ) && $_POST[ \'cf-name\' ] == \'\' ) {
        $errors->add(\'name_error\', \'Please fill in a valid name.\' );
      }
    
      if ( isset( $_POST[ \'cf-email\' ] ) && $_POST[ \'cf-email\' ] == \'\' ) {
        $errors->add(\'email_error\', \'Please fill in a valid email.\' );
      }
    
      if ( isset( $_POST[ \'cf-message\' ] ) && $_POST[ \'cf-message\' ] == \'\' ) {
        $errors->add(\'message_error\', \'Please fill in a valid message.\' );
      }
    
      return $errors;
    }
    
    您的消毒功能。这是一个清理空白和转义html的通用函数,但这可能会更复杂,具体取决于您的输入字段。但我想对你来说已经足够了

    function my_sanitize_field( $input ){
    
      return trim( stripslashes( sanitize_text_field ( $input ) ) );
    
    }
    
    显示成功/错误消息时,您可以使用它来检索WP\\U错误对象

    function my_form_message(){
    
      global $errors;
      if( is_wp_errors( $errors ) && empty( $errors->errors ) ){
    
        echo \'<div class="cf-success">\';
        echo \'<p>Thank you for contacting us \'. $_POST[\'cf-name\'] .\', a member of our team will be in touch with you shortly.</p>\';
        echo \'</div>\';
    
        //Empty $_POST because we already sent email
        $_POST = \'\';
    
      }
      else {
    
      if( is_wp_errors( $errors ) && ! empty( $errors->errors ) ){
    
        $error_messages = $errors->get_error_messages(); 
        foreach( $error_messages as $k => $message ){
            echo \'<div class="cf-error \' . $k . \'">\';
            echo \'<p>\' . $message . \'</p>\';
            echo \'</div>\';
    
        }
    
      }
    
    }
    
    最后是您的短代码函数

    add_shortcode( \'contact_form\', \'cf_contact_form\' );
    function cf_contact_form() {
    
      ob_start();
    
      my_form_message();
      html_form_code();
    
      return ob_get_clean();
    }
    
    并连接到init 倾听$_POST 在呈现窗体并输出$errors 如果我们找到一些或发送,如果一切都好。

    add_action( \'init\', \'my_cf_form\');
    function my_cf_form(){
    
      if( isset( $_POST[\'cf-submitted\'] ) ) {
    
        global $errors;
        $errors = my_validate_form(); 
        if( empty( $errors->errors ) ){
    
           $args = array(
             \'name\'    => my_sanitize_field( $_POST[\'cf-name\'] ),
             \'email\'   => my_sanitize_field( $_POST[\'cf-email\'] ),
             \'message\' => my_sanitize_field( $_POST[\'cf-message\'] ),
           );
           deliver_mail( $args );
        }
        else {
          return $errors;
        } 
      }
    }
    
    请记住始终为函数添加前缀,以免与其他插件函数名称冲突。

    SO网友:Greg McMullen

    由于您对PHP有些陌生,下面是一个很好的示例simple server side honeypot.

    您要做的是在表单中设置一个隐藏的文本字段,并检查它是否为空以捕获垃圾邮件。

    表单HTML

    <label for="honeypot" class="bot">Leave blank if you are human</label>
    <input type="text" id="honeypot" name="honeypot" class="bot" />
    

    CSS

    .bot { display:none }
    
    PHP(简化)
     if ( $_POST() ) {
        $name = strip_tags(urldecode(trim($_POST[\'name\'])));
        // OR
        $name = test_input($_POST[\'name\']; 
        $honeypot = $_POST(\'honeypot\');
        // Only checks IF something is in it.
        if ($honeypot){
          $msg = "You are a bot";
        } else {
          $msg = "Success";
          // Additional processing
          if ($name){
              mail(...)
          }
        }
        echo $msg;
     }
    
    在简短的搜索之后,我还发现了您可以使用的这个函数。

    function test_input($data) {
      $data = trim($data);
      $data = stripslashes($data);
      $data = htmlspecialchars($data);
      return $data;
    }
    

    相关推荐

    Show form per shortcode

    这是我的密码。我想按短代码显示它。$user_id = get_current_user_id(); $balance = mycred_get_users_balance( $user_id ); echo "Current Balance: ".$balance."<br><br>"; if ($_POST && $_SERVER["REQUEST_METHOD"] == &qu