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


PHP форма с капчей

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

Для начала начнем с файла form у него я сменил разрешение с html на php, так как нам придется и в нем прописывать php код и первое, что мы прописываем это запуск сессий:

<?php
Session_start();
?>

Это обязательно необходимо так как мы будем в дальнейшем использовать глобальные переменные $_SESSION для передачи данных. Далее в этом файле будет добавлено еще всего 3 строчки:

<label for="captcha">Введите текст с картинки:</label><br />
<img src="captcha/captcha.php" class="regcapcha" width="150" height="41" id="captcha" /><span class="reload" onclick="document.getElementById('captcha').src = 'libs/captcha/captcha.php?' + Math.random()">Обновить</span><br />
<input type="text" name="checkcapcha" />

Давайте разбираться по порядку от простого к сложному, для начала у нас добавился тег label с меткой о вводе картинки и поле ввода куда соответственно вводить и назвали его checkcapcha. Далее, как вы понимаете капча, это по сути изображение, с которого необходимо, что либо ввести поэтому для её создания используем тег картики img только путь к файлу картинки src мы прописываем на php файл captcha который будет находится в папке captcha он и будет формировать само изображение и передавать необходимые переменные, для соблюдения последовательности давайте рассмотрим, что из себя представляет этот файл и как он работает:

<?php
session_start();
$str = substr(md5(time()),0,5);
$img = imagecreatefromjpeg('bg_captcha.jpg');
$text_color = imagecolorallocate ($img, 0,0,0);
for ($i=0, $x = 20; $i < strlen($str); $i++) {
$size = mt_rand(20, 30);
$angle = mt_rand(-30, 40);
imagettftext($img, $size, $angle, $x, 30, $text_color, 'arial.ttf',$str{$i});
$x += 25;
}
$_SESSION['captcha'] = $str;
header("Content-type: image/jpeg");
imagejpeg($img);

И снова первым делом запускаем сессии благодаря функции session_start(), далее нам необходимо создать то, что мы будем вводить с картинки, то есть нам нужен какой-либо набор символов, цифр, который будет постоянно меняться и быть непредсказуемым. Для решения этой проблемы мы используем стандартную функцию time() которая выдает текущее время, для усложнения, кодируем полученный результат md5 с помощью функции и получаем md5(time()) в итоге у нас получается 32 символа которые будут меняться при каждом обновлении, но так как в капче используется как правило 4-6 символов, нам необходимо это все как то обрезать, для этого так же есть стандартная функция substr(md5(time()),0,5) она обрезает лишнее, вы можете взять как с середины символы, так и с конца, я же взял первые 5, задав параметры 0,5. Все у нас есть 5 символов которые нам необходимо отобразить на капче, но для их использования, необходимо их записать в какую либо переменную я назвал её $str.

То, что будем выводить на капче мы сгенерировали, теперь нам необходимо создать код, который бы сделал нам фоновый рисунок, в данном случае так называемый шумовой фон. Для этого используем простую функцию imagecreatefromjpeg() она создает новое изображение из файла формата jpg, путь к которому прописываем в скобках, естественно файл я заранее обработал и сделал его нужным для меня размером а именно 150x41 пикселей, в интернете огромное количество всевозможных фонов, можно легко найти и обработать скажем в фотошопе. После чего значение данной функции присваиваем переменной $img.

Теперь нам необходимо задать цвет текса, который будет выводиться в данной капче и снова необходимо применить функцию на этот раз это imagecolorallocate – выделение цвета для изображения, здесь присутствует два основных параметра, первый это изображение, второй цвет в формате RGB и результат работы этой функции мы присваиваем переменной $text_color.

С основными настройками практически все осталось грамотно все скомпоновать и вывести для этого есть еще одна функция imagettftext – записывает текст на изображение с использованием ttf шрифтов. Синтаксис функции:

 imagettftext(изображение, размер шрифта, угол наклона текса, отступ по оси х, отступ по оси y, цвет текста, расположение шрифта, сам текст) 

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

Для реализации поставленной задачи используем цикл for в котором создаем переменную $i и присваиваем ей значение 0, с каждым выполненным циклом её значение будет увеличиваться на 1 с помощью $i++, до того момента пока значение переменной $i меньше длины строки $str, посчитать длину строки мы можем с помощью функции strlen(), а у нас их как вы помните 5, тем самым мы сможем присвоить особые параметры каждому символу. При каждом выполнении цикла у нас будут меняться размер текста с помощью функции mt_rand(10, 30); которая будет случайным образом выдавать размер в диапазоне от 10 до 30 пикселей значение каждый раз будет записываться в переменную $size, размеры вы естественно можете поменять изменив значения диапазона, но это на ваш вкус. Так же будет менять угол наклона той же функцией и записывать их в переменную $angle, будет меняться отступ по оси х, изначально он задан как 20, и при каждом цикле будет увеличиваться на 25, благодаря $x +=25, больше не чего трогать не будем. На ваше усмотрение вы можете здесь пофантазировать и поменять еще отступы по оси y и поэкспериментировать с цветом текста, но я этого делать не буду. В итоге мы получаем следующее:

imagettftext($img, $size, $angle, $x, 30, $text_color, 'arial.ttf',$str{$i});

где изображение задаем переменной $img, размер берем из переменной $size, угол наклона $angle, координаты по оси х с помощью переменной $x, ось у задаем без изменений 30, цвет текста переменная $text_color, путь к файлу шрифта так как он находится в той же папке что и файл каптчи то просто прописываем его, по поводу шрифта тут дело ваше можете найти в интернете кучу интересных и красивых шрифтов и тупо пропишите название и поместите в папку, главное чтобы шрифт был ttf, и последнее сам текст, его выводит переменная $str со значением $i. В результате выполнения этого цикла мы получи изображение с выведенным на нем 5 символами с разными размерами, углами наклона и отступами.

Теперь нам необходимо с помощью сессий, передать значение переменной $str в фалй send.php, как я говорил в начале для этого нам и нужно запускать сессии в начале каждого php файла, чтобы мы смогли сравнить то, что введет пользователь с сгенерированным значением капчи.

$_SESSION['captcha'] = $str;

Для этого в глобальный массив $_SESSION с ячейкой capcha мы записываем значение переменной $str. Теперь мы передаем заголовок с типом данных

header("Content-type: image/jpeg");

И выводим изображение в браузер с помощью простой функции imagejpeg($img);, вот и все капча готова, нам осталось только сравнить переданные данные с введенными пользователем, для этого переходим в файл send.php и добавляем следующее:

if(empty($Checkcaptcha)) {
$stop = '<div
class="myform_error"><div class="box"><h1>Вы не ввели капчу</h1></div></div>';
exit($stop);
}
if($Checkcaptcha != $_SESSION ['captcha']) {
$stop = '<div
class="myform_error"><div class="box"><h1>Вы ввели неверный код с картинки:</h1></div></div>';
exit($stop);
}

Тут достаточно просто первым делом, как и в предыдущем уроке мы обрабатываем значение, полученное из поля ввода капчи, затем присваиваем его переменной $Ceckcaptcha и сравниваем с тем значением которое было сгенерировано в файле captcha.php благодаря глобальному массиву $_SESSION если они совпадают, то все пройдет удачно, если же значения разные, то выдаст ошибку.

Теперь снова вернемся к файлу form.php и здесь осталось объяснить последний момент, а именно обновление картинки на капче, так как бывает, что человек не может разобрать значение, которое видит, для этого возле рисунка есть, текст «обновить», нажав на который рисунок изменится, вот как это работает:

<span class="reload" onclick="document.getElementById('captcha').src = 'captcha/captcha.php?' + Math.random()">Обновить</span>

Здесь мы уже применяем JavaScrippt при нажатии на текст скрипт находит в файле элемент с id = captcha и передает рандомный параметр методом get в файл captcha.php, что собственно и позволяет сгенерировать новую картинку, если бы мы не использовали рандомный параметр, то рисунок бы оставался одним и тем же так как браузер воспринимал бы его как один и тот же. Ну и естественно добавили стиль к кнопке обновления, интересный параметр cursor: pointer; он делает курсор как при наведении на ссылку, хотя по сути это не ссылка а просто текст, но так проще воспринимать пользователям.

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

Дата: 2017-03-30
Автор: Алексей Мезенцев
HTML5 и CSS3 с Нуля до Гуру

HTML5 и CSS3

Научись создавать профессиональные современные сайты на HTML5 и CSS3

Узнать подробности