Капча на PHP
Капчу на PHP, или проверочный код, позволяющий отличить человека от робота, каждый из Вас вводил многократно: при регистрации, при отправлении сообщения, при поиске на сайте и много, где ещё. И в этой статье мы с Вами разберём скрипт, реализующий капчу на PHP, а также я Вам покажу, как использовать данный скрипт.
Сначала скачайте скрипт капчи на PHP. Извлекайте архив и помещайте его на Ваш сайт.
Теперь о том, как добавить капчу на форму, например, на форму регистрации:
<form name="register" action="register.php" method="post">
Поля для регистрации...
<h3>Проверчный код</h3>
<img src = "captcha.php" />;
<input type = "text" name = "kapcha" />
<input type = "submit" value = "Регистрация" />
</form>
В результате, на форме регистрации Вы увидите проверочный код, который пользователь должен будет ввести. Теперь о том, как проверить правильность ввода. Для этого в файле "register.php" (или в другом файле, который указан в атрибуте "action") пишем следующие строки:
session_start();
if($_POST['kapcha'] != $_SESSION['rand_code']) echo "Капча введена неверно";
else echo "Капча введена верно";
То есть считываем то, что ввёл пользователь ($_POST['kapcha']) и сравниваем с тем, что находится в сессии (данное значение было записано при генерации капчи). Если значения не совпадают, то делаем вывод, что капча введена неправильно, иначе делаем вывод, что капча введена верно. То есть дальше Вы можете, основываясь на результат сравнения выполнить определённые действия. Например, зарегистрировать пользователя или отправить его вновь на форму регистрации, хотя, безусловно, это зависит от Вашей задачи.
Если Вы хотите научиться самостоятельно создавать подобные скрипты, то посмотрите мой Видеокурс "PHP и MySQL с Нуля до Гуру": http://srs.myrusakov.ru/php
-
- Михаил Русаков
Комментарии (61):
Эта капча очень слабая и можно легко написать скрипт который будет распозновать его. Михаил, советую поменять капчу при регистрации.
Ответить
Капча является формальной, однако, какой смысл автоматической регистрации на моём сайте? У меня свой движок, своя система, поэтому никто не будет возиться с ним. Это никому не нужно, потому и капча чисто формальная, которая сделана максимально простой для обычных людей.
Ответить
А зачем тогда капча вообще нужна?
Ответить
Для защиты от авторегистраций. А вдруг кому-нибудь понадобится? Это Вам кажется, что капча очень лёгкая, уверяю, что разработать подобный алгоритм распознавания очень тяжело, поэтому человек передумает заниматься авторегистрацией на моём сайте.
Ответить
Я немного усовершенствовал рисунок (сделал его меньше по высоте на 10 пикселей) и теперь нижние хвосты немного обрезаны. Такие, как "j" сканер определяет как "i", а "y" как "v", "p" как "o" или "D" ну и так далее. Просто нижняя часть скрыта настолько, что человек поймет, какая это буква, а fine reader нет :)
Ответить
А я вобщем просто не заморачивался и скачал другой шрифт с корявыми буквами, в коде заменил verdana.tff на название моего шрифта и всё =)
Ответить
В какое место вставить session_start(); if($_POST['kapcha'] != $_SESSION['rand_code']) echo "Капча введена неверно"; else echo "Капча введена верно"; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/> <title>Обратная связь</title> </head> <body> <?php if (isset($_POST['name'])) {$name = $_POST['name'];} if (isset($_POST['email'])) {$email = $_POST['email'];} if (isset($_POST['mess'])) {$mess = $_POST['mess'];} if (empty($name)) { echo "<b>Не указано имя!<p>"; echo "<a href=contacts.html>Вернуться к заполнению формы</a>"; exit; } if (empty($email)) { echo "<b>Не указан e-mail!<p>"; echo "<a href=contacts.html>Вернуться к заполнению формы</a>"; exit; } if (empty($mess)) { echo "<b>Сообщение не написано!<p>"; echo "<a href=contacts.html>Вернуться к заполнению формы</a>"; exit; } $to = "[email protected]"; /*УКАЗАТЬ СВОЙ АДРЕС!*/ $headers = "Content-type: text/plain; charset = windows-1251"; $subject = "Сообщение с вашего сайта"; $message = "Имя пославшего: $name \nЭлектронный адрес: $email \nСообщение: $mess"; $send = mail ($to, $subject, $message, $headers); if ($send == 'true') { echo "<b>Спасибо за отправку вашего сообщения!<p>"; echo "<a href=index.html>Нажмите,</a> чтобы вернуться на главную страницу"; } else { echo "<p><b>Ошибка. Сообщение не отправлено!"; } ?> </body> </html>
Ответить
Обычно вставляют прямо в начале скрипта.
Ответить
примерчик сделайте пожалйста
Ответить
Какой пример? Начало скрипта сразу после <?php Но если не понимаете, то вот пример: <?php session_start(); echo "Сессия началась"; ?>
Ответить
ВОТ ТАК ПРАВИЛЬНО ИЛИ НЕТ? <?php session_start(); if($_POST['kapcha'] != $_SESSION['rand_code']) echo "Капча введена неверно"; else echo "Капча введена верно";
Ответить
Правильно.
Ответить
Вот такая ошибка Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at
Ответить
Одно из двух: 1. Что-то до <?php выводите, например, пробел. Иногда выводят даже HTML-теги. 2. Кодировка UTF-8, хотя нужно ставить кодировку UTF-8 без BOM.
Ответить
Здравствуйте. Скрипт, проверяющий капчу, выдает: Cannot send session cache limiter - headers already sent (output started at...) Я так думаю, это из-за того, что сессия запускается повторно. Первая была в генераторе капчи. Как можно решить эту проблему?
Ответить
Нет, проблема не в этом. Проблема в том, что сессия запускается ПОСЛЕ какого-нибудь echo или любого другого вывода в браузер. Ещё это может быть из-за проблемы с кодировкой. Надо ставить не UTF-8, а UTF-8 без BOM.
Ответить
Простите, а как можно исключить вывод в браузер, если в самом генераторе капчи жизненно необходим вывод в браузер изображения? Сессия там запускается при старте генератора капчи. Или, может быть, в нем можно обойтись и без сессии? (например, просто сформировав массив из пяти случайных чисел в результате работы цикла for?). И еще один вопрос. Можно ли организовать проверку введенного кода, не используя "session start"?
Ответить
Так начинайте сессию ДО вывода капчи.
Ответить
Так в том то и проблема, что и в генераторе есть session_start(), и в обработчике кпчи - тоже. Ваш пример: session_start(); if($_POST['kapcha'] != $_SESSION['rand_code'])... Так вот, если я убираю отсюда "session_start();", обработчик капчи перестает правильно распознавать вводимые мною числа - что бы я ни вводил, правильно ли, неправильно ли, все равно эффект один и тот же - пишет: "неправильно введены числа с картинки", хотя я уверен, что все ввожу правильно. Снова вставляю в обработчик "session start", и он начинает работать, как надо, но появляется вышеприведенная ошибка.
Ответить
Исправляйте свой код, он не является нормальным.
Ответить
Здравствуйте, Михаил. А как сделать чтобы буквы выводились не по левому краю, а посередине?
Ответить
Изменить координаты в самом скрипте при генерации капчи.
Ответить
А какие именно параметры отвечают за положение символов?
Ответить
imagettftext ($image, 30, 0, 10, 40, $color, $dir."verdana.ttf", $_SESSION['rand_code']);
Ответить
Спасибо, первый координат я понял отвечает за размер, второй - за угол наклона, третий - положение по горизонтали, четвертый - по вертикали.
Ответить
Есть ли вообще смысл распознавать капчу роботом каждый раз, если хранить ответ в сессии? можно просто один раз ввести с картинки, сохранить, скопировать куку php-сессии и регистрироваться миллионы раз! Такую програмку я могу написать за 20 минут, более того, с помощью такой програмки конкуренты сайта могут забить тебе базу mysql за очень короткий срок! По-этому надо задуматься о том, стоит ли вообще доверять встроенным сессиям в php... я, например использую собственный класс сессии, значения которого хранятся тоже в кукисах (шифруется с помощью Rijndael(AES) + дополнительные крипты и хеши), в нем присутствует ключ с указанием времени жизни сессии, ip-адреса, user-agent'а ну еще нескольких финтов..(это все настраивается в конфигах). Но сессии использую только для авторизированных пользователей, для капчи использую зашифрованный куки с временем жизни 60 секунд(в самом куки хранится информация о времени его создания, поэтому копирование не прокатит), естественно капча тоже обновляется каждые 50 секунд(с запасом в 10сек) с помощью яваскрипта.
Ответить
Мощно! А раскритикуете мою капчу? _http://lifeexample.ru/php-primeryi-skriptov/kapcha-na-php.html
Ответить
а как сделать капчу по типу сложения, например записать ответ(1+3)
Ответить
Хорошо, напишу такую статью в понедельник.
Ответить
Михаил, спасибо за статью и вообще за сайт. Но у меня неувязочка выходит: файл captcha.php сам по себе открывается нормально-картинка есть. Но в другом файле через <img src = "captcha.php" alt="" /> не отображается в броузере. В firebug можно видеть , что <img> как будто бы в режиме hidden - написание осветленное, но если курсор остановить на src то в всплывающем инфо картинка загружается нормально... С чего могут быть такие проблемы? Спасибо!
Ответить
Если по src картинка появляется, то всё должно работать. Может у Вас действительно где-то в стилях картинка скрывается.
Ответить
случилось что-то страшное: после экспериментов с капчой на localhoste вобще все картинки перестали отображаться....
Ответить
Переустановить попробуйте.
Ответить
Целый день сегодня все переустанавливал, были проблемы с Вампом (проблемы с Aeston Menu и доступом на сервер). Все установил, а проблема осталась... Сами по себе картинки открываются, но в файлах РНР они не видны. Но слава Богу, как оказалось что такая беда только с Firefox, в Chrome все нормально отображается. Вобщем, проблема между Фоксом и с локальным сервером. С удаленным сервером нормально работает. Михаил, спасибо за ваши быстрые ответы и если у Вас будут какие=нибудь идеи по моей проблеме с Фоксом буду очень признателен.
Ответить
C firefox может быть ещё проблема в кэшировании картинки. Попробуйте поиграться с его настройками и проверить.
Ответить
Спасибо за совет попробую!
Ответить
Igor, такая же проблема, что и у Вас, в firefox не вставляется картинка по src, нашли решение?
Ответить
нет, не нашел. использую Хром.
Ответить
Помогите разобраться. В форму вставил, всё заработало. А вот дальше проблемы код: <?php session_start(); if($_POST['kapcha'] != $_SESSION['rand_code']) echo "Капча введена неверно"; else echo "Капча введена верно"; $to = $_POST['to']; // $tema = $_POST['tema']; $from = $_POST['from']; $message = $_POST['msg']; $header = "From: ".$from; mail($to, $tema, $message, $header); ?> Выдаёт ошибку строку 2 (session_start();), если введено не верно или верно, но в любом случае письмо уходит к адресату. Тест проводил на денвере.
Ответить
Надо после того, как капча введена неверно, делать редирект обратно, а не продолжать скрипт.
Ответить
Если не трудно напишите этот самый редирект, а то уже устал экспериментировать.
Ответить
header("Location: ".$_SERVER["HTTP_RERFERER"]); exit;
Ответить
<?php session_start(); if($_POST['kapcha'] != $_SESSION['rand_code']) echo "Капча введена неверно"; else echo "Капча введена верно"; header("Location: ".$_SERVER["HTTP_RERFERER"]); exit; $to = $_POST['to']; $tema = $_POST['tema']; $from = $_POST['from']; $message = $_POST['msg']; $header = "From: ".$from; mail($to, $tema, $message, $header); ?> Капча введена неверно Warning: Cannot modify header information - headers already sent by (output started at Z:\home\...\www\mail\mail.php:3) in Z:\home\...\www\mail\mail.php on line 5 Капча введена верно Warning: Cannot modify header information - headers already sent by (output started at Z:\home\...\www\mail\mail.php:4) in Z:\home\...\www\mail\mail.php on line 5
Ответить
echo перед header() - это абсурд. Это всё равно, что лошадь впереди телеги. Рекомендую ознакомиться с этой статьёй: http://myrusakov.ru/php-how-study.html
Ответить
Напишите как надо. Ставил после exit; и тоже выдаёт ошибку. Статья не внесла ясности.
Ответить
Статья должна внести ясности в том, что не надо делать регистрацию, если не знаете, что такое header(). Я мог бы написать (это ровно 3 строчки), но не буду, ибо это будет вред Вам. Здесь учатся, а готовые скрипты "скопируй не думая, вставь не думая" на других сайтах.
Ответить
Как то так <?php session_start(); if($_POST['kapcha'] != $_SESSION['rand_code']) { echo 'Капча введена неверно'; exit; } else { header ('Refresh: 3; URL=адрес куда отправлять'); //Время редиректа и куда отправлять пользователя $to = $_POST['to']; $tema = $_POST['tema']; $from = $_POST['from']; $message = $_POST['msg']; $header = "From: ".$from; mail($to, $tema, $message, $header); echo 'Сообшение успешно отправлено'; exit; } ?>
Ответить
Как быть если на странице несколько капч то-есть в 1 блоке форма регистрации в другом блоке во фрейме выводится мини чат, это надо для каждого обработчика делать скрипт с отдельной капчей? Просто картинки на капчах при регистрации и в миничате совпадают.
Ответить
Надо делать разные файлы с капчей, и везде генерировать случайность и записывать в сессию оба значения. А потом проверять.
Ответить
А какой смысл разукрашивать буквы в капче, если боту это будет абсолютно всё равно?
Ответить
Для красоты.
Ответить
Лучше шрифт поменяйте на посложнее. И хоть на пару слов разбейте.
Ответить
Михаил, а как сделать если капча правильная,то переходила на определёную ссылку?
Ответить
Через редирект: http://myrusakov.ru/redirekt-php.html
Ответить
Спасибо за урок! очень помогло!!!
Ответить
Здравствуйте Дмитрий! Спасибо за урок, установил капчу в форму обратной связи, но выдается ошибка, что неправильно введен текст. Как я понимаю, при нажатии мною кнопки "submit" в $_POST['captcha'] попадает новое значение капчи, а не то которое ввожу. Как от этого избавиться? Привожу код обработчика: <?php include "config.php"; if($_POST['submit']){ session_start(); // определяем переменные $name = substr($_POST['name'], 0, 20); $mail = substr($_POST['mail'], 0, 20); $text = substr($_POST['text'], 0, 2000); $captcha = $_POST['captcha']; // проверка заполнения обязательных полей $error = ''; $pattern = "/^.+@[a-z0-9]+\.[a-z]{2,6}$/i"; if(empty($name)) $error = '<li>Не заполнено поле "Имя"</li>'; if(empty($mail)) $error .= '<li>Не заполнено поле "Email"</li>'; if(empty($text)) $error .= '<li>Не заполнено поле "Сообщение"</li>'; if(empty($captcha)) $error .= '<li>Не заполнено поле "Введите текст с картинки"</li>'; if(!empty($mail) and !preg_match($pattern, $mail)) $error .= '<li>Поле "Ваш Email:" не соответствует установленному формату</li>'; if($_POST['сaptcha'] != $_SESSION['rand_code']) $error .= '<li>Символы с картинки введены неверно</li>'; if(empty($error)) { // определяем переменные $to = '[email protected]'; $subject = "\r\n".'Заполнена форма на сайте'. "\r\n"; $message = "\r\n"."Имя: " .$name. "\r\n"; $message .= "Обратный e-mail: " .$mail. "\r\n"; $message .= "Текст сообщения: " .$text. "\r\n"; $headers = "Content-type: text/plain; charset = \"utf-8\""; // формируем сообщение if(mail($to, $subject, $message, $headers)) { $_SESSION['res'] = $name.', Ваше письмо успешно отправлено.'; header("Location: $site_url?option=contacts"); exit(); } else { $_SESSION['res'] = 'Произошла ошибка. Попробуйте еще раз.'; header("Location: $site_url?option=contacts"); exit(); } } else { $_SESSION['res'] = "Не заполнены обязательные поля:<ul>" .$error. "</ul>"; $_SESSION['name'] = $name; $_SESSION['mail'] = $mail; $_SESSION['text'] = $text; $_SESSION['captcha'] = $captcha; header("Location: $site_url?option=contacts"); exit(); } } ?>
Ответить
Код обработчика должен находиться в отдельном файле, откуда можно сделать редирект назад, передав результаты проверки через сессию или GET.
Ответить
Михаил, обработчик("action"), который указывается в форме у меня естественно в отдельном файле, я вам его и показал выше. А вложение форм, чтобы указать еще один "action" не допускается. Но я нашел выход, я код капчи из файла img.php поместил в файле обработчика после if($_POST['submit']), соответственно в форме указал src="mail.php"(т.е. обработчик). Таким образом, при нажатии на кнопку отправки сообщения в массив POST попадает не новое значение капчи, а то, которое я ввожу в поле input. Еще раз огромное спасибо за Ваши уроки, они мне очень помогают. Михаил, у меня к Вам просьба, расскажите пожалуйста, как сделать так, чтобы при отправке сообщений страница в браузере не перескакивала в начало, так как становится не видно сообщения об отправке сообщения или регистрации. И еще, хотелось бы узнать каким редактором пользуются на форумах для того чтобы можно было вставлять код. Было бы хорошо вообще такой урок сделать. Я умею прикручивать CKEditor, но он не очень меня устраивает. Заранее благодарю. С уважением Игорь Нагай
Ответить
Здравствуйте Михаил!!! Попробовал установить КАПЧУ из вашего примера к себе на сайт, НО почему то в форме с выводом капчи картинка НЕ выводится. Я убрал все лишние файлы, оставил только папку font, файл captcha.php и в пустой файл Index.html вставил код формы с капчей и всё ровно картинка не выводится???? Файл chaptcha.php изображение генерит нормально, видимо загвоздка в строке <img src = "captcha.php" /> В чём дело, что я делаю неправильно?????
Ответить
Разобрался частично, действительно код рабочий, КАПЧА выводится. Причина кроется в следующем: файл captcha.php должен обязательно лежать в корне сайта. Если его положить во вложенную папку (например lib) то конструкция <img src = "lib/captcha.php" /> уже не срабатывает. А вот почему???? вот это вопрос. Если к примеру загружать просто картинку из каталога lib (например <img src = "lib/logo.png" /> - картинка загружается, а captcha.php НЕТ. В ЧЁМ ПРИЧИНА ?????? Поясните Михаил!!!!!!!!!
Ответить
Класно, мне нравиться
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.