Contact Form 7のwpcf7_spamフィルターでしっかりスパム対策を行おう

記事カテ:コード

この記事を読むのに約6分かかる

掲載日:

この課題を扱った多くの記事では、Contact Form 7 (WPCF7) で日本語以外の入力を阻止するため、バリデーション(wpcf7_validate)と Regex(正規表現)によっての実装方法が紹介されています。 バリデーションであれば人間のユーザーによる日本語以外のテキスト入力を防ぐことはできます、ロボットやクローラーを防ぐことはできません

この記事では、フロントエンド(wpcf7_validate)とバックエンド(wpcf7_spam)でともにスパム対策を使ってブログを保護する方法を紹介します。

今回の例では、コンタクトフォームの「your-name」(Contact Form 7 のデフォルトの「name」)フィールドを使い、ユーザーが入力できる文字を日本語だけに制限します。

Regex(正規表現)

ここでは、regex(regex とは)と PHP のファンクションpreg_match()を使って、名前の有効性を判断します。 このファンクションは 2 つのパラメーターを受け取る。regex の表現とユーザーの名前(String)です。

今回使用する regex 表現は ``/^[ぁ-んァ-ヶ一-龠々+ー+]+$/u` です。この表現では、文字列がすべての日本語文字(「ー」を含む)で構成されているかどうかを判断します。

バリデーション(フロントエンド)

最初のステップはフロントエンド(ユーザー側)です。ユーザーが無効な名前(日本語の文字がないもの)を入力した場合、エラーを表示させて、ロボットじゃないユーザーが今回正しく日本語の名前を再入力できるようにする必要があります。 そのために、WPCF7 の「wpcf7_validate」というフィルターを使い、メッセージを検証するカスタムファンクションをフィルターに渡します。

コードはこちら:

function wpcf7_validation_function($result, $tag) {
// WPCF7フォームから入力した最初の値をとって、$valueにいれる
$value = str_replace(array(PHP_EOL, ' '), '', esc_attr($_POST['your-name']));
if (!empty($value)) { // $valueが空でなければ
if (!preg_match("/^[ぁ-んァ-ヶ一-龠々+ー+]+$/u", $value)) { // 名前の文字が全て日本語じゃなければ…
$result['valid'] = false; // 名前が無効だとWPCF7に教える変数
$result['reason'] = array('your-name' => 'お名前は日本語で入力してください'); // ユーザーエラーメッセージを表示する。このメッセージを変えてもオッケー!
}
}
return $result;
}
add_filter('wpcf7_validate', 'wpcf7_validation_function', 10, 2);

wpcf7_spam(バックエンド)

次に、WPCF7 がバリデーション対策を通過したスパムお問い合わせをバックエンド(サーバー)に受け付けないようにする必要があります。 このためには、wpcf7_spamというフィルターを使います。 (公式ドキュメント [英語]

ここでもフィルターファンクションを操作して、入力された名前がスパムかどうかを WPCF7 に伝えるようにしています。

コードはこちら:

add_filter('wpcf7_spam', function ($spam) {
if ($spam) { return $spam; } // 他のフィルターによって、$spamはすでに「true」となっている場合があるから、ここではtrueならそのままreturnする
$value = $_POST['your-name']; // フィールドの値を$valueに
if (!empty($value)) { // $valueが空でなければ
if (!preg_match("/^[ぁ-んァ-ヶ一-龠々+ー+]+$/u", $value)) { // 名前の文字が全て日本語じゃなければ…
$spam = true; // スパムだ!!
}
}
return $spam;
}, 10, 1);

$spam が「true」の場合、そのお問い合わせは WPCF7 によってスパムと判断され、あなたとユーザーはメールが送信されることはありません。これで完成!

コードまとめ

function wpcf7_validation_function($result, $tag) {
$value = str_replace(array(PHP_EOL, ' '), '', esc_attr($_POST['your-name']));
if (!empty($value)) {
if (!preg_match("/^[ぁ-んァ-ヶ一-龠々+ー+]+$/u", $value)) {
$result['valid'] = false;
$result['reason'] = array('your-name' => 'お名前は日本語で入力してください');
}
}
return $result;
}
add_filter('wpcf7_validate', 'wpcf7_validation_function', 10, 2);
add_filter('wpcf7_spam', function ($spam) {
if ($spam) { return $spam; }
$value = $_POST['your-name'];
if (!empty($value)) {
if (!preg_match("/^[ぁ-んァ-ヶ一-龠々+ー+]+$/u", $value)) {
$spam = true;
}
}
return $spam;
}, 10, 1);

注目点

スパムと判定された場合、WPCF7 と同じメーカーが作った関連している WPCF7 用のプラグイン「Flamingo」によってそのお問い合わせはを「スパム」として保存されます。なので Flamingo をインストールして受信したスパムを追跡しよう!

ニーズによって、変化する可能性のある変数のリスト:

  • your-name
    • WPCF7 のフィールド名(もちろん「your-message」といった他のフィールドでもこの方法が有効)
  • wpcf7_validation_function
    • フィルターに渡すファンクション名はなんでもいいです
  • Regex 表現
    • また、プロジェクトのニーズに合わせて、正規表現を変更することもできます。Regex 表現によって特定の単語や文字などを禁止することも可能

そんなところですね。日本語で書いた僕の最初の記事! 質問、問題・添削点などがあれば、ぜひ連絡してくださいね!