Уважаемые друзья, форма вопрос - ответ снова в строю!

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

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

Мы все с вами привыкли видеть на сайтах при заполнении любой формы трудночитаемую картинку с рандомными символами и цифрами. Данная картинка называется КАПТЧА (от CAPTCHA— англ. Completely Automated Public Turing test to tell Computers and Humans Apart — полностью автоматизированный публичный тест Тьюринга для различения компьютеров и людей). Как описано в расшифровке аббревиатуры данная картинка позволяет определить робот или человек заполняет форму.

В настоящее время существует множество разновидностей КАПТЧ, это может быть картинка с рандомным текстом, или картинка с математическими действиями, блок картинок в которых нужно выбрать определенные предметы и т.д. Все эти картинки направлены на борьбу с роботами спамерами, которые заполняют формы автоматически.

Стоит понимать что КАПЧА это не панацея, и при желании ее всегда можно распознать автоматически использую соответствующие сервисы. Данная проблема актуальна для высоконагруженных веб сайтов с большой аудиторией, например социальные сети или популярные доски объявлений такие как Авито и т.д.

Переходя от вступления к практики, для написания КАПТЧИ нам понадобится библиотека GD. GD Graphics Library (GD) — программная библиотека, написанная Томасом Баутелом (Thomas Boutell) и другими разработчиками для динамической работы с изображениями. Данная библиотека работает с множеством других языков программирования и служит для работы с графикой. Как вы уже догадались, мы будем с помощью библиотеки GD и PHP создавать свою картинку с рандомным текстом. Graphics Library позволяет также редактировать существующие изображения, а именно наложение логотипа на картинку, изменения размеров загружаемого изображения и многое другое.

Список функция для работы с графикой в PHP
  • gd_info — Вывод информации о текущей установленной GD библиотеке
  • getimagesize — Получение размера изображения
  • getimagesizefromstring — Получение размера изображения из строки данных
  • image_type_to_extension — Получение расширения файла для типа изображения
  • image_type_to_mime_type — Получение Mime-типа для типа изображения, возвращаемого функциями getimagesize, exif_read_data, exif_thumbnail, exif_imagetype
  • image2wbmp — Выводит изображение в браузер или пишет в файл
  • imageaffine — Return an image containing the affine transformed src image, using an optional clipping area
  • imageaffinematrixconcat — Concatenate two affine transformation matrices
  • imageaffinematrixget — Get an affine transformation matrix
  • imagealphablending — Задание режима сопряжения цветов для изображения
  • imageantialias — Требуется ли применять функции сглаживания или нет
  • imagearc — Рисование дуги
  • imagechar — Рисование символа по горизонтали
  • imagecharup — Рисование символа вертикально
  • imagecolorallocate — Создание цвета для изображения
  • imagecolorallocatealpha — Создание цвета для изображения
  • imagecolorat — Получение индекса цвета пиксела
  • imagecolorclosest — Получение индекса цвета ближайшего к заданному
  • imagecolorclosestalpha — Получение индекса цвета ближайшего к заданному с учетом прозрачности
  • imagecolorclosesthwb — Получение индекса цвета, имеющего заданный тон, белизну и затемнение
  • imagecolordeallocate — Разрыв ассоциации переменной с цветом для заданного изображения
  • imagecolorexact — Получение индекса заданного цвета
  • imagecolorexactalpha — Получение индекса заданного цвета и альфа компонента
  • imagecolormatch — Делает цвета палитровой версии изображения более соответствующими truecolor версии
  • imagecolorresolve — Получает идентификатор конкретного цвета или его ближайший аналог
  • imagecolorresolvealpha — Получает идентификатор конкретного цвета и альфа компонента или его ближайший аналог
  • imagecolorset — Установка набора цветов для заданного индекса палитры
  • imagecolorsforindex — Получение цветов, соответствующих индексу
  • imagecolorstotal — Определение количества цветов в палитре изображения
  • imagecolortransparent — Определяет цвет как прозрачный
  • imageconvolution — Наложение искривляющей матрицы 3х3, используя коэффициент и смещение
  • imagecopy — Копирование части изображения
  • imagecopymerge — Копирует часть изображения с наложением
  • imagecopymergegray — Копирует часть изображения с наложением в градациях серого
  • imagecopyresampled — Копирование и изменение размера изображения с ресемплированием
  • imagecopyresized — Копирование и изменение размера части изображения
  • imagecreate — Создание нового палитрового изображения
  • imagecreatefromgd2 — Создание нового изображения на основе GD2 или URL
  • imagecreatefromgd2part — Создание нового изображения на основе части GD2 файла или URL
  • imagecreatefromgd — Создание нового изображения на основе GD файла или URL
  • imagecreatefromgif — Создает новое изображение из файла или URL
  • imagecreatefromjpeg — Создает новое изображение из файла или URL
  • imagecreatefrompng — Создает новое изображение из файла или URL
  • imagecreatefromstring — Создание нового изображения из потока представленного строкой
  • imagecreatefromwbmp — Создает новое изображение из файла или URL
  • imagecreatefromwebp — Создает новое изображение из файла или URL
  • imagecreatefromxbm — Создает новое изображение из файла или URL
  • imagecreatefromxpm — Создает новое изображение из файла или URL
  • imagecreatetruecolor — Создание нового полноцветного изображения
  • imagecrop — Crop an image using the given coordinates and size, x, y, width and height
  • imagecropauto — Crop an image automatically using one of the available modes
  • imagedashedline — Рисование пунктирной линии
  • imagedestroy — Уничтожение изображения
  • imageellipse — Рисование эллипса
  • imagefill — Заливка
  • imagefilledarc — Рисование и заливка дуги
  • imagefilledellipse — Рисование закрашенного эллипса
  • imagefilledpolygon — Рисование закрашенного многоугольника
  • imagefilledrectangle — Рисование закрашенного прямоугольника
  • imagefilltoborder — Заливка цветом
  • imagefilter — Применяет фильтр к изображению
  • imageflip — Flips an image using a given mode
  • imagefontheight — Получение высоты шрифта
  • imagefontwidth — Получение ширины шрифта
  • imageftbbox — Определение границ текста выводимого шрифтом freetype2
  • imagefttext — Нанесение текста на изображение, используя шрифты FreeType 2
  • imagegammacorrect — Применение гамма коррекции к GD изображению
  • imagegd2 — Вывод GD2 изображения в браузер или файл
  • imagegd — Вывод GD-изображения в браузер или в файл
  • imagegetclip — Get the clipping rectangle
  • imagegif — Выводит изображение в браузер или пишет в файл
  • imagegrabscreen — Захватывает изображение с экрана
  • imagegrabwindow — Захватывает изображение окна
  • imageinterlace — Включение или выключение интерлейсинга
  • imageistruecolor — Определяет, является ли изображение полноцветным
  • imagejpeg — Выводит изображение в браузер или пишет в файл
  • imagelayereffect — Установка флага альфа сопряжения для использования эффектов наложения изображений
  • imageline — Рисование линии
  • imageloadfont — Загрузка шрифта
  • imagepalettecopy — Копирование палитры из одного изображения в другое
  • imagepalettetotruecolor — Converts a palette based image to true color
  • imagepng — Вывод PNG изображения в браузер или файл
  • imagepolygon — Рисование многоугольника
  • imagepsbbox — Выдает параметры рамки, обрамляющей текст написанный шрифтом PostScript Type1
  • imagepsencodefont — Изменение вектора кодировки шрифта
  • imagepsextendfont — Растягивание или сжатие шрифта
  • imagepsfreefont — Освобождение памяти, занятой шрифтом PostScript Type
  • imagepsloadfont — Загрузка шрифта PostScript Type 1 из файла
  • imagepsslantfont — Наклон шрифта
  • imagepstext — Рисование текста поверх изображения, используя шрифты PostScript Type1
  • imagerectangle — Рисование прямоугольника
  • imagerotate — Поворот изображения с заданным углом
  • imagesavealpha — Установка флага сохранения всей информации альфа компонента (в противовес одноцветной прозрачности) и сохранение PNG изобаржения
  • imagescale — Scale an image using the given new width and height
  • imagesetbrush — Установка изображения (кисти), посредством которого будут рисоваться линии
  • imagesetclip — Set the clipping rectangle
  • imagesetinterpolation — Set the interpolation method
  • imagesetpixel — Рисование точки
  • imagesetstyle — Установка стиля рисования линий
  • imagesetthickness — Установка толщины линий
  • imagesettile — Установка изображения, которое будет использовано в качестве элемента мозаичной заливки
  • imagestring — Рисование строки текста горизонтально
  • imagestringup — Рисование строки текста вертикально
  • imagesx — Получение ширины изображения
  • imagesy — Получение высоты изображения
  • imagetruecolortopalette — Преобразование полноцветного изображения в палитровое
  • imagettfbbox — Получение параметров рамки обрамляющей текст написанный TrueType шрифтом
  • imagettftext — Рисование текста на изображении шрифтом TrueType
  • imagetypes — Возвращает список типов изображений, поддерживаемых PHP сборкой
  • imagewbmp — Выводит изображение в браузер или пишет в файл
  • imagewebp — Output a WebP image to browser or file
  • imagexbm — Вывод XBM изображения в браузер или файл
  • iptcembed — Встраивание двоичных IPTC данных в JPEG изображение
  • iptcparse — Разбор двоичных IPTC данных на отдельные тэги
  • jpeg2wbmp — Конвертирует изображение из формата JPEG в WBMP
  • png2wbmp — Преобразование PNG файла в WBMP

Определим требования к нашей КАПТЧе для ее реализации:

  • Размер холста 200 х 60
  • Фон холста RGB(255, 181, 181)
  • Шрифт verdana.ttf
  • Рандомные лини на холсте с рандомным цветом
  • Генератор строки для КАПТЧИ
  • Рандомный цвет символов и углом наклона
  • Рандомное количество и цвет точек на холсте
  • Обновление КАПТЧИ без перезагрузки страницы (Jquery)
  • КАПТЧА чувствительна к регистру
  • Плашка с URL нашего сайта

Приступаем к написанию КАПТЧИ. Первое что нам нужно – это генератор случайных чисел. Такой генератор я писал в одной из статей Генератор пароля + соль в пароле для хранения в MySQL. Так же необходимо загрузить файл шрифта на сервер для использования его в КАПТЧе.

Создаем файл captcha.php

<?php
/**
* КАПТЧА 1.0
* Site: http://bezramok-tlt.ru
* Создание КАПТЧИ своими руками
* Autor: Админ
*/

//Запускаем сессию
session_start();

//Устанавливаем кодировку и вывод всех ошибок
header('Content-Type: text/html; charset=UTF-8');
error_reporting(E_ALL);

function getRandString($num)
{
    //Генерим массив из букв
    $letter = range('a', 'z');
    //Генерим массив из цифр
    $number = range(0, 9);

    //Создаем строку с маленькими и большими буквами и цифрами
    $letter = implode('',$letter);
    $letter = $letter.strtoupper($letter).implode('',$number);

    //Строка с генерированым кодом
    $randStr = '';
    for ($i = 0; $i < $num; $i++){
        //Прогоняем циклом столько, сколько нужно символов в строке
        $randStr .= $letter[rand(0, strlen($letter) - 1)];
    }
    return $randStr;
}

//Функция генерации цвета
function randColor($imgPng, $red = null, $green = null, $blue = null)
{
    if(is_numeric($red) and is_numeric($green) and is_numeric($blue))
        return imagecolorallocate($imgPng, $red, $green, $blue);
    else
        return imagecolorallocate($imgPng, rand(0, 255), rand(0, 255),rand(0, 255));
}

//Путь до нужного шрифта
$fonts = "./font/verdana.ttf";

//Нижняя плашка каптчи
$url = "http://bezramok-tlt.ru";

//Размер шрифта каптчи
$fontSize    = 24;
$fontSizeUrl = 12;

//Размеры холста холста
$width  = 200;
$height = 80;

//Количество линий и пикселей на холсте
$countLine = rand(0, 10);
$countPixel = rand(200, 1000);

// Сколько символов будем выводить на картинке
$numbers = 5;

//Получаем сгенерированую строку
$randStr = getRandString($numbers);

// Записываем каптчу в сессию
$_SESSION['captcha'] = $randStr;

// Создаем картинку (холст) размером 200 X 60
$imgPng = imagecreatetruecolor($width, $height);

// Создаем фон холста, RGB(255, 181, 181)
$imgColor   = randColor($imgPng, 255, 181, 181); 

//Зададим цвет линиям, у меня он динамический
$lineСolor  = randColor($imgPng);

//Зададим цвет для точек, у меня он динамический
$pixelСolor = randColor($imgPng);

//Цвет текста, у меня он динамический
$textColor  = randColor($imgPng);

//Цвет полоски с текстом в низу картинки
$bgColor  = randColor($imgPng, 0, 0, 0);

//Цвет текста URL красный
$redColor  = randColor($imgPng, 255, 0, 0);

//Определяем фон картинки
imagefilledrectangle($imgPng, 0, 0, $width, $height, $imgColor);

//Создаем линии на холсте
for ($i = 0; $i < $countLine; $i++) {
	imageline($imgPng, 0, rand(0, $height), $width, rand(0, $height), $lineСolor);
}

//Создаем точки на холсте
for ($i = 0; $i < $countPixel; $i++) {
    imagesetpixel($imgPng, rand(0, $width) , rand(0, $height), $pixelСolor);
}

//Пишем по букве не холсте
for ($i = 0; $i < strlen($randStr); $i++)
  {
    //Растояние между символами
    $x = ($width - 20) / strlen($randStr) * $i + 10;
    
    //Случайное смещение
    $x = rand($x, $x + 4);

    //Координата Y
    $y = $height - (($height - $fontSize) / 2 );

    //Случайны цвет отдельного символа
    $letterColor = randColor($imgPng);
    
    //Случайный угол наклона символов 
    $angle = rand(-25, 50);

    //Пишем текст на холсте (наш код каптчи)
    imagettftext($imgPng, $fontSize, $angle, $x, $y, $letterColor, $fonts, $randStr[$i]);
  }

// создаем рамку для текста
$bbox = imagettfbbox($fontSizeUrl, 0, $fonts, $url);

//Высчитываем координаты для выравнивания по центру
$textX = $bbox[0] + (imagesx($imgPng) / 2) - ($bbox[4] / 2);

//Определяем фон картинки
imagefilledrectangle($imgPng, 0, 60, $width, $height, $bgColor);

//Надпись с URL
imagettftext($imgPng, $fontSizeUrl, 0, $textX, 75, $redColor, $fonts, $url);


// Посылаем заголовок серверу о том что у нас картинка в формате png
header("Content-type: image/png");
imagepng($imgPng);

//Освобождаем
imagedestroy($imgPng);

?>

Если обратиться к этому файлу через браузер, то мы получим вот такую картинку.

Создание каптчи bezramok-tlt.ru
Создаем файл с разметкой form.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">	
	<meta charset="UTF-8">
	<!-- Latest compiled and minified CSS -->
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
	<title>Document</title>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-md-6 col-md-offset-3">
				<h1 class="text-center">Форма работы каптчи:</h1>
				<!-- Выводим ошибки -->
				<?php 
					if(count($err) > 0)
						echo '<div class="alert alert-danger">'. implode('<br>', $err).'</div>';
					
					if(!empty($ok))
						echo '<div class="alert alert-success">'. $ok .'</div>';

				?>
				<form method="POST" action="">
				  <div class="form-group">
				    <label for="exampleInputEmail1">Email</label>
				    <input type="email" class="form-control" id="exampleInputEmail1" name="email" placeholder="Email">
				  </div>
				  <div class="form-group">
				    <label for="code">Код с картинки</label>
				    <input type="text" class="form-control" id="code" name="captcha" placeholder="Код с картинки">
				  </div>
				  <div class="form-group">
				    <p class="help-block"><img id="captcha" src="captcha.php" alt=""> <button class="btn btn-default" id="refreshImg"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button></p>

				  </div>
				  <button type="submit" class="btn btn-primary" name="send">Отправить</button>
				</form>
			</div>
		</div>
	</div>
<script src="http://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
	$(document).ready(function(){

		$('#refreshImg').click(function(e){
			e.preventDefault();
			$('#captcha').attr('src', 'captcha.php?r=' + Math.random());
		})
	});
</script>
</body>
</html>

Далее создаем файл обработчик нашей формы с КАПТЧей

Создаем файл обработчик формы index.php

<?php
	/**
	* Главный файл
	* Site: http://bezramok-tlt.ru
	* Создание КАПТЧИ своими руками
	*/

	//Запускаем сессию
	session_start();

	//Устанавливаем кодировку и вывод всех ошибок
	header('Content-Type: text/html; charset=UTF8');
	error_reporting(E_ALL);

	//Инициализируем переменные для работы
	$err = array();

	//Если нажата кнопка отправки формы
	if(isset($_POST['send']))
	{
		//Утюжим пересенные
		if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
			$err[] = 'Не верный email!';

		if($_SESSION['captcha'] != $_POST['captcha'])
			$err[] = 'Код с картинки не совпадает!';

		if(empty($err))
			$ok = 'Вы прошли проверку!';
	}

	//Подключаем наш шаблон
	include './form.html';
?>
я заметил
23:57:06 14/03/2017г.
Привет, админ, сделай новый урок, система друзей, то есть что бы можно было добавить друг друга в друзья, принять отклонить, оставить его в подписках, как вк.

Мне кажется, что данная тема очень узко направленная и не всем интересна. Так что не стоит ждать в ближайшее время.

- Администрация     - 09:52:37 17/03/2017г.

я заметил
11:04:41 10/03/2017г.
Админу привет, такой вопрос пробую поставить твою капчу и мне не удается это сделать правильно, она установилась, но когда ввожу числа, мне всегда говорят что я ввел не правильно ее.

Где может быть моя ошибка?

Посмотри что ты отправляешь на сервер в POST


echo '<pre>';
print_r($_POST);
echo '</pre>';

- Администрация     - 12:02:30 10/03/2017г.

я заметил
14:52:49 07/10/2016г.
О уже перезалил) Отлично) Может поможешь мне? если не сложно, пожалуйста!

Вечером поймай меня. Пока на работе.

- Администрация     - 14:53:48 07/10/2016г.

я заметил
14:41:24 07/10/2016г.
Админ перезалей файл, С Уважением к разработчику!

И еще одно как сделать мне тоже обновить капчу?

В моей капче?

Привет, перезолил.


В шаблон в ставь где каптчу нужно вывести:



<img src="captcha.php" alt="capthca">

- Администрация     - 14:52:58 07/10/2016г.

  • 1

Получить уведомление на Email

Введите код с картинки