2017
4
Фев

Как сделать капчу (captcha) php для сайта

grigoriev
2708
капча (capcha) php
скачать капча (captcha) php
DOWNLOAD
пример капча (captcha) php
DEMO

Для защиты сайта от регистрации ботов используют так называемый тест Тьюринга. В простонародии он называется капча (CAPTCHA). Я решил сделать капчу (captcha) используя php. Об этом и пойдёт разговор в этой заметке.

Что же по сути такое тест Тьюринга. А это проверка, является ли пользователь живым человеком или ботом. Устанавливается задача, которую человек решит легко, а для программного решения потребуется очень много ресурсов. Обычно задачей является распознавание текста на картинке. Для усложнения распознования картинки с помощью компьютера добавляют к изображению дополнительные линии и шумы. Исходя из выше изложенной информации, напрашивается вывод, что мы должны научиться генерировать изображения с помощью php. Для работы с графикой в php существует библиотека GD2. Давайте сначала её подключим и разберёмся как с её помощью сделать captcha для сайта.

Подключение библиотеки GD2 к PHP

Находим в папке: C:\Program Files\PHP\ext файл php_gd2.dll(это и есть библиотека), и копируем в c:\windows. В файле c:\windows\php.ini находим строку extension=php_gd2.dll и раскоментируем. Не забываем перезапустить apache. У меня веб сервер apache стоит на windows. Здесь заметка как я его ставил. Так что процесс установки GD2 может у вас отличаться от моего. Теперь давайте разберём основные функции GD2.

Функции библиотеки GD2 PHP

Создание и генерация изображения

Функция Что функция делает
$myimg = imageCreate(500, 300) Делаем изображение (256 цветов)
$myimg = imageCreateTrueColor(500, 300) Делаем изображение (17 млн. цветов)
header("Content-type: image/jpeg"); imageJpeg($myimg[,"filename"][,quality]) Создание JPEG-картинки
header("Content-type: image/gif"); imageGif ($myimg[,"filename"]); Создание GIF-картинки
header("Content-type: image/png"); imagePng($myimg[,"filename"]); Создание PNG-картинки

Рисование

Функция Что функция делает
imageAntiAlias($myimg, true) Сглаживание (antialiasing)
$mycolor = imageColorAllocate($myimg, 255, 0, 0) Определение цвета
imageLine($myimg, 25, 25, 70, 290, $mycolor); Рисуем линии, цифры это координаты точек
imageRectangle($myimg, 25, 25, 70, 290, $mycolor); Рисуем прямоугольник, цифры это координаты углов
imageFilledRectangle ($myimg, 20, 20, 65, 295, $mycolor); Заливка фона
$points = array(0,0,110,210,310,210); imagePolygon($myimg, $mypoints, 3, $mycolor); imageFilledPolygon ($myimg, $mypoints, 3, $mycolor); Рисуем многоугольник
imageEllipse ($myimage, 200, 150, 300, 200, $color); Рисуем эллипс. Первые 2е цифры координаты центра эллипса, 2е 2е высота и ширина эллипса (x, y)
imageString ($myimage, 3, 130, 350, "Hai", $mycolor); Рисуем строку текста. 1я цифра размер шрифта ( max 5)
imageTtfText ($myimg, 30, 10, 310, 160, $mycolor, "my.ttf", "Hai"); Рисуем строку текста. Применяем TrueType-шрифты. 1я цифра размер шрифта, 2я угол наклона, 3-4 координаты бокса, шрифт, текст
$myimg = imageCreateFromJPEG("myimage.jpg"); $myimg = imageCreateFromGIF("myimage.gif"); $myimg = imageCreateFromPNG("myimage.png"); Делаем новое изображения на базе имеющегося

Создание капчи (captcha) php

Теперь мы обладаем нужной информацией для создания капчи (captcha) php. Я написал свой небольшой класс, который генерирует картинку капчи. Файл с классом называется mycaptcha.php. Листинг ниже.

<?php
class mycaptcha{
//сюда получаем сгенерированную капчу        
    public $keycaptcha;

    function captcha(){
//создаём картинку
        $myimg = imageCreateTrueColor(250, 50);
//количество символов
        $nChars=5;
//генерируем captcha
        $randStr=substr(md5(uniqid()),0,$nChars);
        $this->keycaptcha=$randStr;
//задаём подложку из картинки
        $myimg = imageCreateFromJPEG("noise.jpg");
        imageAntiAlias($img, true);
//генерируется случайное число от 1 до 4        
        function getColor(){
            $x=rand(1,4);
            return $x;
        }
//координата символа по гориз.
        $j=20;
        for ($i = 0; $i < 5; $i++) {
//получаем $i символ из сгенерир.
            $z=substr($randStr, $i, 1);
//рандомно получаем размер символа
            $size=rand(25,30);
//рандомно получаем угол поворота символа
            $angle=-30+rand(0,60);
//получаем рандомно цвет символа
            $n=getColor();
            switch ($n) {
                case 1:  $c=imageColorAllocate($myimg, 255, 0, 0); break;
                case 2:  $c=imageColorAllocate($myimg, 0, 200, 0); break;
                case 3:  $c=imageColorAllocate($myimg, 0, 0, 255); break;
                case 4:  $c=imageColorAllocate($myimg, 0, 0, 0); break;
            }
//генерируем картинку
imageTtfText($myimg, $size, $angle, $j, 30, $c,"bellb.ttf", "$z");
$j+=35;
        }
//выводим captcha
        header("Content-type: image/jpeg");
        imageJpeg($myimg);
    }
    function getKeycaptcha(){
            return $this->keycaptcha;
    }    
}
?>    

Теперь нам этот класс нам нужно подключить в файл, который будет генерировать captcha php. Файл я назвал imgcaptcha.php. Листинг:

<?php
//запускаем сессию
    session_start();
//подключаем класс
    include('mycaptcha.php');
//вызываем класс
    $captcha = new mycaptcha();
//генерим капчу
    $captcha->captcha();
//записываем значение капчи в сессию
    $_SESSION['keycaptcha'] = $captcha->getKeycaptcha();
?>    

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

Теперь нам осталось подключить captcha php на сайт. Для этого надо создать файл, где мы будем выводить капчу и проверять правильность её введения. Назовём этот файл index.php. Листинг ниже.

<?php
header("Content-Type: text/html; charset=utf-8");
//запустим сессию
session_start();
//создадим переменную
$result="";
/*ф-я фильтрации*/
function myclear($dt){
    $dt=stripslashes($dt);
    $dt=strip_tags($dt);
    $dt=trim($dt);
    return $dt;
}
//проверим была ли отправлена форма
if($_SERVER["REQUEST_METHOD"]=="POST"){
//проверка существования сессионной переменной
//браузер запрашивает картинку, если графика
//отключена переменной не существует
  if (isset($_SESSION['keycaptcha'])){
//если капча введена правильно
    if($_SESSION['captcha_keystring']==myclear($_POST["str"])){
      $result="Капча введена верно.";
    }else{
      $result="Капча введена неверно!!! Вы ввели: "
      .myclear($_POST["str"])."Капча была: "
      .$_SESSION['keycaptcha'];
    }
  }else{
      $result="ВКЛЮЧИ ГРАФИКУ!";
  }
}
?>

<img src="/imgcaptcha.php" id="captcha">

<button type="button" onclick="document.getElementById('captcha').src = 
            'imgcaptcha.php?' + Math.random()"</button>
<form  action="" method="post">
    <input type="text" name="str" placeholder="Введите капчу">
    <button type="submit" >Отправить</button>
</form>        
<?php
//вывод сообщения
    echo $result;
//очищаем сессию
    unset($_SESSION['keycaptcha']);
?>

Разберёмся что происходит в index.php. Мы выводим капчу, выведя imgcaptcha.php как картинку. В форму мы вводим значение капчи и отсылаем его методом post самим себе. Так же получаем значение капчи из сессии. Это значение, которое сгенерировалось классом и вывелось в виде картинки. Сравниваем значение капчи введённое в поле и полученное из сессии. В зависимости от проверки выводим сообщение. Обращу ваше внимание на такую вот конструкцию js onclick="document.getElementById('captcha').src = 'imgcaptcha.php?' + Math.random(). При клике по кнопке происходит перезагрузка картинки капчи. Что бы изображение не кешировалось к адресу картинки imgcaptcha.php добавляется случайное число с помощью Math.random(). Ну на этом я думаю всё, тема капчи php раскрыта. Я думаю уже не должно возникать вопросов как сделать капчу (captcha) php для сайта. Если есть вопросы, задавайте их в комментариях.

Поделиться:

Комментарии

Николай

Николай

19.02.2017 18:51 Ответить

Хорошая, интересная, полезная статья!

Виктор

Виктор

15.09.2017 11:24 Ответить

Класс капчи сделан криво. Без конструктора создается две капчи, и в сессию пишется первая. Соответственно проверка не работает

Виктор

Виктор

15.09.2017 11:28 Ответить

class captcha{
public $keycaptcha;
private function getColor(){
$x=rand(1,4);
return $x;
}
public function __construct(){}
public function captcha(){
$myimg = imageCreateTrue Color(250, 50);
$nChars=5;
$randStr=substr (md5(uniqid()), 0,$nChars);
$this->keycaptc ha=$randStr;
$myimg = imageCreateFrom JPEG("../../img /noise.jpg");
imageAntiAlias( $myimg, true);
$j=20;

Виктор

Виктор

15.09.2017 13:14 Ответить

for ($i = 0; $i < 5; $i++) {
$z=substr($rand Str, $i, 1);
$size=rand(25,3 0);
$angle=-30+rand (0,60);
$n=$this->getCo lor();
switch ($n) {
case 1: $c=imageColorAl locate($myimg, 255, 0, 0); break;
case 2: $c=imageColorAl locate($myimg, 0, 200, 0); break;
case 3: $c=imageColorAl locate($myimg, 0, 0, 255); break;
case 4: $c=imageColorAl locate($myimg, 0, 0, 0); break;
}
imageTtfText($m yimg, $size, $angle, $j, 30, $c,"../../fonts /bellb.ttf", "$z");
$j+=35;
}
header("Content -type: image/jpeg");
imageJpeg($myim g);
imagedestroy($m yimg);
}
public function getKeycaptcha() {
return $this->keycaptc ha;
}
}

Алексей Григорьев

Алексей Григорьев

15.09.2017 15:43 Ответить

В демо примере вроде все работает нормально. А что вам даёт конструктор?

Добавить комментарий


Защитный код
Обновить