Статьи

Создайте свою собственную капчу и контактную форму на PHP

Люди пишут код каждый день, чтобы автоматизировать различные процессы. Мы используем тот факт, что компьютеры работают намного быстрее и точнее, чем люди, что позволяет нам упростить множество повседневных задач. К сожалению, эти же возможности могут быть использованы для программирования компьютеров на что-то вредоносное, например, рассылку спама или подбора паролей. Основное внимание в этом руководстве будет уделено борьбе со спамом.

Допустим, у вас есть веб-сайт с контактной формой, чтобы посетители могли с вами связаться. Все, что им нужно сделать, это заполнить форму и нажать кнопку «Отправить», чтобы сообщить вам о проблеме или запросе, который у них есть. Это важная функция общедоступного веб-сайта, но злоумышленники могут автоматизировать процесс заполнения значений формы, чтобы отправлять большое количество спама на ваш путь. Этот тип техники рассылки спама не ограничивается только контактными формами. Ботов также можно использовать для заполнения ваших форумов спам-сообщениями или комментариями, которые ссылаются на вредоносные веб-сайты.

Одним из способов решения этой проблемы является разработка теста, который будет различать ботов, которые пытаются распространять спам, и людей, которые на законных основаниях хотят с вами связаться. Вот здесь и появляются капчи. Обычно они состоят из изображений со случайной комбинацией из пяти или шести букв, написанных на цветном фоне. Идея в том, что человек сможет читать текст внутри изображения, а бот — нет. Проверка заполненного пользователем значения CAPTCHA по сравнению с оригиналом может помочь вам отличить ботов от людей. CAPTCHA означает «полностью автоматизированный общедоступный тест Тьюринга, позволяющий разделить компьютеры и людей».

В этом уроке мы узнаем, как создавать наши собственные CAPTCHA, а затем интегрируем их с формой контакта, которую мы создали в уроке.

Мы будем использовать библиотеку PHP GD для создания нашей капчи. Вы можете узнать больше о написании текста и рисовании фигур с помощью GD в одном из моих предыдущих уроков. Нам также придется написать немного кода для создания нашей случайной строки, которая будет написана на созданном изображении. Еще одно руководство под названием « Генерация случайных буквенно-цифровых строк в PHP» может помочь нам в этом.

Весь код из этого раздела будет помещен в файл captcha.php . Давайте начнем с написания функции для создания случайной строки.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<?php
 
$permitted_chars = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’;
  
function generate_string($input, $strength = 5) {
    $input_length = strlen($input);
    $random_string = »;
    for($i = 0; $i < $strength; $i++) {
        $random_character = $input[mt_rand(0, $input_length — 1)];
        $random_string .= $random_character;
    }
  
    return $random_string;
}
 
$string_length = 6;
$captcha_string = generate_string($permitted_chars, $string_length);
 
 
?>

Переменная $permitted_chars хранит все символы, которые мы хотим использовать для генерации нашей строки CAPTCHA. Мы используем только заглавные буквы в английском алфавите, чтобы избежать путаницы, которая может возникнуть из-за букв или цифр, которые могут выглядеть одинаково. Вы можете использовать любой набор символов, который вам нравится увеличивать или уменьшать сложность капчи.

Наша функция по умолчанию создает пятибуквенную строку, но вы можете изменить это значение, передав другой параметр в функцию generate_string() .

Как только мы получим нашу случайную строку, пришло время написать код для создания фона изображения CAPTCHA. Изображение будет иметь размер 200 x 50 пикселей и будет использовать пять разных цветов для фона.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
 
$image = imagecreatetruecolor(200, 50);
 
imageantialias($image, true);
 
$colors = [];
 
$red = rand(125, 175);
$green = rand(125, 175);
$blue = rand(125, 175);
 
for($i = 0; $i < 5; $i++) {
  $colors[] = imagecolorallocate($image, $red — 20*$i, $green — 20*$i, $blue — 20*$i);
}
 
imagefill($image, 0, 0, $colors[0]);
 
for($i = 0; $i < 10; $i++) {
  imagesetthickness($image, rand(2, 10));
  $rect_color = $colors[rand(1, 4)];
  imagerectangle($image, rand(-10, 190), rand(-10, 10), rand(-10, 190), rand(40, 60), $rect_color);
}
 
?>

Начнем со случайных значений переменных $red , $green и $blue . Эти значения определяют окончательный цвет фона изображения. После этого мы запускаем цикл for для создания постепенно темных оттенков исходного цвета. Эти цвета хранятся в массиве. Самый светлый цвет — это первый элемент нашего массива $colors , а самый темный цвет — последний элемент. Самый светлый цвет используется для заполнения всего фона изображения.

На следующем шаге мы используем цикл for для рисования прямоугольников в случайных местах на нашем исходном изображении. Толщина прямоугольников варьируется от 2 до 10, а цвет выбирается случайным образом из последних четырех значений нашего массива $colors .

Рисование всех этих прямоугольников добавляет больше цветов к фону, делая его немного труднее отличить передний план строки CAPTCHA от фона изображения.

Ваш фон CAPTCHA должен выглядеть примерно так, как показано на следующем рисунке.

CAPTCHA фон в PHP

Для последнего шага нам просто нужно нарисовать строку CAPTCHA на нашем фоне. Цвет, координата y и поворот отдельных букв определяются случайным образом, что затрудняет чтение строки CAPTCHA.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
 
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$textcolors = [$black, $white];
 
$fonts = [dirname(__FILE__).’\fonts\Acme.ttf’, dirname(__FILE__).’\fonts\Ubuntu.ttf’, dirname(__FILE__).’\fonts\Merriweather.ttf’, dirname(__FILE__).’\fonts\PlayfairDisplay.ttf’];
 
$string_length = 6;
$captcha_string = generate_string($permitted_chars, $string_length);
 
for($i = 0; $i < $string_length; $i++) {
  $letter_space = 170/$string_length;
  $initial = 15;
   
  imagettftext($image, 20, rand(-15, 15), $initial + $i*$letter_space, rand(20, 40), $textcolors[rand(0, 1)], $fonts[array_rand($fonts)], $captcha_string[$i]);
}
 
header(‘Content-type: image/png’);
imagepng($image);
imagedestroy($image);
 
?>

Как вы можете видеть, я использую некоторые шрифты, которые я скачал с Google, чтобы получить варианты символов. С обеих сторон изображения имеется отступ 15 пикселей. Оставшееся пространство — 170 пикселей — делится поровну между всеми буквами CAPTCHA.

После рендеринга текстовой строки над фоном ваш результат должен выглядеть примерно так, как показано ниже. Символы будут отличаться, но они должны быть немного повернуты и смешать черное и белое.

CAPTCHA фон с текстом

Теперь, когда мы создали нашу CAPTCHA, пришло время добавить ее в нашу контактную форму. Мы будем использовать контактную форму из моего предыдущего урока о том, как создать контактную форму PHP и добавить CAPTCHA чуть выше кнопки « Отправить сообщение» .

Мы будем использовать сеансы для хранения текста CAPTCHA, а затем проверять текст, введенный посетителями сайта. Вот полный код нашего файла captcha.php :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
 
session_start();
 
$permitted_chars = ‘ABCDEFGHJKLMNPQRSTUVWXYZ’;
  
function generate_string($input, $strength = 10) {
    $input_length = strlen($input);
    $random_string = »;
    for($i = 0; $i < $strength; $i++) {
        $random_character = $input[mt_rand(0, $input_length — 1)];
        $random_string .= $random_character;
    }
  
    return $random_string;
}
 
$image = imagecreatetruecolor(200, 50);
 
imageantialias($image, true);
 
$colors = [];
 
$red = rand(125, 175);
$green = rand(125, 175);
$blue = rand(125, 175);
 
for($i = 0; $i < 5; $i++) {
  $colors[] = imagecolorallocate($image, $red — 20*$i, $green — 20*$i, $blue — 20*$i);
}
 
imagefill($image, 0, 0, $colors[0]);
 
for($i = 0; $i < 10; $i++) {
  imagesetthickness($image, rand(2, 10));
  $line_color = $colors[rand(1, 4)];
  imagerectangle($image, rand(-10, 190), rand(-10, 10), rand(-10, 190), rand(40, 60), $line_color);
}
 
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$textcolors = [$black, $white];
 
$fonts = [dirname(__FILE__).’\fonts\Acme.ttf’, dirname(__FILE__).’\fonts\Ubuntu.ttf’, dirname(__FILE__).’\fonts\Merriweather.ttf’, dirname(__FILE__).’\fonts\PlayfairDisplay.ttf’];
 
$string_length = 6;
$captcha_string = generate_string($permitted_chars, $string_length);
 
$_SESSION[‘captcha_text’] = $captcha_string;
 
for($i = 0; $i < $string_length; $i++) {
  $letter_space = 170/$string_length;
  $initial = 15;
   
  imagettftext($image, 24, rand(-15, 15), $initial + $i*$letter_space, rand(25, 45), $textcolors[rand(0, 1)], $fonts[array_rand($fonts)], $captcha_string[$i]);
}
 
header(‘Content-type: image/png’);
imagepng($image);
imagedestroy($image);
?>

Шрифты, которые вы хотите использовать, попадут в каталог шрифтов . Теперь вам просто нужно добавить следующий HTML-код над кнопкой « Отправить сообщение» из нашего предыдущего урока по созданию контактной формы в HTML и PHP .

1
2
3
4
5
6
<div class=»elem-group»>
    <label for=»captcha»>Please Enter the Captcha Text</label>
    <img src=»captcha.php» alt=»CAPTCHA» class=»captcha-image»><i class=»fas fa-redo refresh-captcha»></i>
    <br>
    <input type=»text» id=»captcha» name=»captcha_challenge» pattern=»[AZ]{6}»>
</div>

Иногда текст CAPTCHA будет трудно читать даже людям. В этих ситуациях мы хотим, чтобы они могли запрашивать новую CAPTCHA в удобной для пользователя форме. Значок повторения выше помогает нам сделать именно это. Все, что вам нужно сделать, это добавить JavaScript ниже на той же странице, что и HTML-код для контактной формы.

1
2
3
4
var refreshButton = document.querySelector(«.refresh-captcha»);
refreshButton.onclick = function() {
  document.querySelector(«.captcha-image»).src = ‘captcha.php?’
}

После интеграции CAPTCHA в форму и добавления кнопки обновления вы должны получить форму, похожую на изображение ниже.

Форма обратной связи PHP с CAPTCHA

Последний шаг в нашей интеграции CAPTCHA, который мы создали с формой контакта, включает проверку значения CAPTCHA, вводимого пользователями при заполнении формы, и сопоставление его со значением, сохраненным в сеансе. Обновите файл contact.php из предыдущего руководства, чтобы получить следующий код.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
 
session_start();
 
if($_POST) {
    $visitor_name = «»;
    $visitor_email = «»;
    $email_title = «»;
    $concerned_department = «»;
    $visitor_message = «»;
 
    if(isset($_POST[‘captcha_challenge’]) && $_POST[‘captcha_challenge’] == $_SESSION[‘captcha_text’]) {
     
        if(isset($_POST[‘visitor_name’])) {
            $visitor_name = filter_var($_POST[‘visitor_name’], FILTER_SANITIZE_STRING);
        }
         
        if(isset($_POST[‘visitor_email’])) {
            $visitor_email = str_replace(array(«\r», «\n», «%0a», «%0d»), », $_POST[‘visitor_email’]);
            $visitor_email = filter_var($visitor_email, FILTER_VALIDATE_EMAIL);
             
        }
         
        if(isset($_POST[’email_title’])) {
            $email_title = filter_var($_POST[’email_title’], FILTER_SANITIZE_STRING);
        }
         
        if(isset($_POST[‘concerned_department’])) {
            $concerned_department = filter_var($_POST[‘concerned_department’], FILTER_SANITIZE_STRING);
        }
         
        if(isset($_POST[‘visitor_message’])) {
            $visitor_message = htmlspecialchars($_POST[‘visitor_message’]);
        }
         
        if($concerned_department == «billing») {
            $recipient = «[email protected]»;
        }
        else if($concerned_department == «marketing») {
            $recipient = «[email protected]»;
        }
        else if($concerned_department == «technical support») {
            $recipient = «[email protected]»;
        }
        else {
            $recipient = «[email protected]»;
        }
         
        $headers = ‘MIME-Version: 1.0’ .
        .’Content-type: text/html;
        .’From: ‘ .
         
        if(mail($recipient, $email_title, $visitor_message, $headers)) {
            echo ‘<p>Thank you for contacting us.
        } else {
            echo ‘<p>We are sorry but the email did not go through.</p>’;
        }
    } else {
        echo ‘<p>You entered an incorrect Captcha.</p>’;
    }
     
} else {
    echo ‘<p>Something went wrong</p>’;
}
 
?>

Мы обновили этот файл, чтобы сначала проверить, совпадает ли значение CAPTCHA, сохраненное в сеансе, со значением, введенным пользователем. Если они отличаются, мы просто сообщаем посетителям, что они ввели неверную CAPTCHA. Вы можете по-разному справиться с ситуацией в зависимости от потребностей вашего проекта.

В этом уроке мы создали нашу собственную CAPTCHA на PHP с нуля и интегрировали ее с контактной формой PHP, которую мы создали в одном из наших предыдущих уроках. Мы также сделали CAPTCHA более удобной для пользователя, добавив кнопку обновления, чтобы пользователи могли получать новую строку с новым фоном на случай, если предыдущая была нечитаемой.

Вы также можете использовать логику из этого учебника для создания CAPTCHA, которая опирается на решение основных математических уравнений, таких как сложение и вычитание.

Если вы хотите добавить CAPTCHA на свой веб-сайт, вы должны проверить некоторые из форм и плагинов CAPTCHA, доступных на CodeCanyon. Некоторые из них имеют CAPTCHA и многие другие функции, такие как встроенный загрузчик файлов.

Если у вас есть какие-либо вопросы или предложения, не стесняйтесь сообщить мне в комментариях. Вам также следует взглянуть на этот список лучших контактных форм PHP .

  • PHP
    12 лучших контактных форм PHP-скриптов
    Нона Блэкман
  • PHP
    Создать контактную форму в PHP