VIPE[R]
Новичок
Со временем сайт набирает популярность и возникает необходимость в организации защиты от спам-ботов. В этой статье я расскажу как можно создать собственную капчу на PHP.
Капча (captcha) представляет из себя изображение с некоторым текстом, который предлагается набрать пользователю в поле ввода для подтверждения его "человечности". Дело в том, что человеку одинаково легко читать текст, независимо от того, является ли он непосредственно машинным текстом или изображением. В то время как компьютеру требуется гораздо более сложный алгоритм для "чтения" текста в виде картинки. Очевидно, что капча каждый раз должна отображать случайную последовательность символов.
Капчи используются, как правило, при заполнении каких-либо форм на сайте. Алгоритм работы следующий: на форме присутствует изображение-captcha с некой случайной последовательностью символов. Рядом с ним имеется поле для ввода содержимого капчи пользователем. Изображение, по сути, является PHP-скриптом, который его формирует. При этом сгенерированное текстовое содержимое капчи где-то сохраняется. При отправке формы скрипт сравнивает сохраненное значение капчи с тем, что ввел пользователь. Если значения совпадают, то запрос принимается, иначе отклоняется.
Предлагаемая мной реализация предельно проста, в то же время, в ней имеется поддержка TrueType шрифтов, а также альфа-канал (прозрачный фон), поэтому капча будет хорошо вписываться в любой дизайн.
Обратите внимание, что для работы скрипта требуется PHP-расширение GD, подключите его в настройках.
Для начала необходимо определиться со шрифтом. Соответствующий выбранному шрифту ttf-файл необходимо положить в директорию с будущим скриптом капчи. Я для капчи выбрал шрифт Comic Sans MS, ему соответствует файл comic.ttf. Файлы шрифтов можно найти в системном каталоге шрифтов вашей операционной системы, либо загрузить из Интернета.
Далее создается скрипт captcha.php. В начале скрипта объявляются необходимые переменные:
Это символы, которые будут участвовать в формировании капчи.
В этой переменной задается длина капчи (6 символов).
Ширина и высота генерируемого изображения. Нужно, во-первых, подобрать размер в соответствии с дизайном вашего сайта, во-вторых, задать оптимальную ширину для указанной длины капчи, чтобы буквы не были слишком плотно прижаты друг к другу.
Здесь указывается файл шрифта. В принципе, его можно разместить в поддиректории, допустим, fonts, тогда содержимое переменной должно быть такого формата: fonts/comic.ttf.
Размер шрифта.
С переменными разобрались. Далее, приступаем непосредственно к реализации. Во-первых, необходимо указать клиенту запрошенного скрипта, что ответный контент представляет из себя не текст, а изображение. Для этого переопределяем содержимое HTTP-заголовка content-type:
Создаем изображение с заданными размерами:
Выставляем флаг необходимости сохранения альфа-канала изображения:
Создаем цвет фона. Это будет полностью прозрачный цвет:
Заливаем этим цветом наше созданное изображение:
Инициализируем переменную, в которой будет содержаться текстовое значение капчи:
Далее организовывается цикл с количеством итераций равным длине капчи (caplen):
На каждом шаге цикла генерируется очередной символ капчи и рисуется на изображении. Берем случайный символ из нашего алфавита и добавляем его в капчу:
Вычисляем положение сгенерированного символа на изображении по оси x:
Это положение зависит от ширины изображения, длины капчи и порядкового номера символа. Далее мы добавляем немного "случайности" в это положение:
Вычисляем положение сгенерированного символа на изображении по оси y:
Положение зависит от размера шрифта и высоты изображения.
Генерируем случайный цвет для символа. Этот цвет не должен быть слишком светлым, поэтому каждый из компонентов цвета (R, G и B) генерируем в диапазоне 0-100:
Для текущего символа случайным образом генерируем его угол наклона в диапазоне -25..25 градусов, чтобы буквы на капче "плясали":
И, наконец, рисуем символ со всеми выше полученными характеристиками на изображении:
На этой строке оканчивается тело цикла. Когда цикл отработает, в переменной captcha будет содержаться текстовое значение капчи, а изображение im будет представлять из себя отрисованную капчу. Необходимо где-то сохранить значение капчи, чтобы основной скрипт, который использует ее, мог проверить значение пользователя. Лучшее для этого место — сессионная переменная. Инициализируем сессию и сохраняем значение капчи:
Наконец, выводим сформированное изображение captcha:
И освобождаем память, выведенную под изображение:
Пример использования капчи:
Обработка формы
Капча (captcha) представляет из себя изображение с некоторым текстом, который предлагается набрать пользователю в поле ввода для подтверждения его "человечности". Дело в том, что человеку одинаково легко читать текст, независимо от того, является ли он непосредственно машинным текстом или изображением. В то время как компьютеру требуется гораздо более сложный алгоритм для "чтения" текста в виде картинки. Очевидно, что капча каждый раз должна отображать случайную последовательность символов.
Капчи используются, как правило, при заполнении каких-либо форм на сайте. Алгоритм работы следующий: на форме присутствует изображение-captcha с некой случайной последовательностью символов. Рядом с ним имеется поле для ввода содержимого капчи пользователем. Изображение, по сути, является PHP-скриптом, который его формирует. При этом сгенерированное текстовое содержимое капчи где-то сохраняется. При отправке формы скрипт сравнивает сохраненное значение капчи с тем, что ввел пользователь. Если значения совпадают, то запрос принимается, иначе отклоняется.
Предлагаемая мной реализация предельно проста, в то же время, в ней имеется поддержка TrueType шрифтов, а также альфа-канал (прозрачный фон), поэтому капча будет хорошо вписываться в любой дизайн.
Обратите внимание, что для работы скрипта требуется PHP-расширение GD, подключите его в настройках.
Для начала необходимо определиться со шрифтом. Соответствующий выбранному шрифту ttf-файл необходимо положить в директорию с будущим скриптом капчи. Я для капчи выбрал шрифт Comic Sans MS, ему соответствует файл comic.ttf. Файлы шрифтов можно найти в системном каталоге шрифтов вашей операционной системы, либо загрузить из Интернета.
Далее создается скрипт captcha.php. В начале скрипта объявляются необходимые переменные:
PHP:
$letters = 'ABCDEFGKIJKLMNOPQRSTUVWXYZabcdefgkijklmnopqrstuvwxyz0123456789';
PHP:
$caplen = 6;
PHP:
$width = 120; $height = 20;
PHP:
$font = 'comic.ttf';
PHP:
$fontsize = 14;
С переменными разобрались. Далее, приступаем непосредственно к реализации. Во-первых, необходимо указать клиенту запрошенного скрипта, что ответный контент представляет из себя не текст, а изображение. Для этого переопределяем содержимое HTTP-заголовка content-type:
PHP:
header('Content-type: image/png');
PHP:
$im = imagecreatetruecolor($width, $height);
PHP:
imagesavealpha($im, true);
PHP:
$bg = imagecolorallocatealpha($im, 0, 0, 0, 127);
PHP:
imagefill($im, 0, 0, $bg);
PHP:
$captcha = '';
PHP:
for ($i = 0; $i < $caplen; $i++)
PHP:
$captcha .= $letters[ rand(0, strlen($letters)-1) ];
PHP:
$x = ($width - 20) / $caplen * $i + 10;
PHP:
$x = rand($x, $x+4);
PHP:
$y = $height - ( ($height - $fontsize) / 2 );
Генерируем случайный цвет для символа. Этот цвет не должен быть слишком светлым, поэтому каждый из компонентов цвета (R, G и B) генерируем в диапазоне 0-100:
PHP:
$curcolor = imagecolorallocate( $im, rand(0, 100), rand(0, 100), rand(0, 100) );
PHP:
$angle = rand(-25, 25);
PHP:
imagettftext($im, $fontsize, $angle, $x, $y, $curcolor, $font, $captcha[$i]);
PHP:
session_start();
$_SESSION['captcha'] = $captcha;
PHP:
imagepng($im);
PHP:
imagedestroy($im);
HTML:
<html>
<head></head>
<body>
<form method='POST'>
<img scr='captcha.php'>
<input type='text' name='test'>
<input type='submit' name='submit'>
</form>
<body>
<html>
PHP:
<?php
session_start();
if(isset($_POST['submit']))
{
if($_SESSION['captcha'] === $_POST['test'])
{
echo "Правильный защитный код";
}
else
{
echo "Неправильный защитный код";
}
}
?>
