web-dev-qa-db-ja.com

フィールド検証付きの簡単な連絡フォーム

私はショートコードで出力できるように非常に簡単な連絡先を作成しようとしています。私は次のコードを持っていますが、それは正しく検証されていないようで、詳細を入力せずにフォームを送信することさえできます。万が一誰かがフォームを検証する方法を説明してください。これらは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
user53340

検証メカニズムはありません。

あなたの論理はややそれらの線に沿っているべきです

  • フォームを送信する
  • 送信されたフィールド($ _POST)を期待値と照合してください
  • すべてが良さそうに見えたら
  • 何かが予想通りでない場合は、エラーをログに記録し(WP_Error()を使用することができます)、エラーメッセージを表示するフォームを再構築します(そしておそらく以前の「良い」値を持つフィールドを再作成します)。

ここで私が見るのはあなたが入力をサニタイズすることだけですが、あなたの入力があなたが期待する値を持っているかどうか実際には検証しません(すなわち有効なEメール、電話、名前の長さなど)。

あなたのフィールドが期待値を持っているかどうかに関係なくあなたはあなたのEメールを送ります。あなたのelseはエラーを出力します _ only _ wp_mail()が失敗した場合、実際のフィールドが検証された値を持っているかどうかではありません。

ハニーポットを追加するには、空になると予想される隠しフィールドをフォームに追加するだけです。

たとえば、あなたのHTMLでは

<input type="text" name="content" id="content" value="" class="hpot" />

その後、フォーム入力を検証すると、そのフィールドは空になります。

WP_Error classを使用すると、後でユーザーに通知するためなどにエラーを使用するために、オブジェクトにエラーを追加できます。

$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_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.
}

_編集_

わかりましたので、これはより完全な例です。

_ 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_mail関数は$_POSTをリ​​ッスンするべきではなく、サニタイズするべきでもありません。ちなみに、フォームユーザーの電子メールをfromヘッダーとして使用すると、一部のISPで問題が発生する可能性があります。電子メールは your ドメインから送信され、ドメインだがfromアドレスに一致しないドメインがある(スパムと見なされる可能性がある)。ここであなたのドメインからのアドレスを使って([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_Errorオブジェクトを取得することができます。

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

他のプラグインの関数名と競合しないように、常に関数の前に付けることを忘れないでください。

2
bynicolas

あなたはPHPに少し慣れていないので、これは 単純なサーバサイドハニーポット の良い例です。

あなたがすることはあなたのフォームに隠しテキストフィールドを設定し、それがスパムを捕まえるために空でないかどうかをチェックすることです。

フォーム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;
}
0
Greg McMullen