Уроки PHP для начинающих


Как сделать и установить капчу

Продолжаем совершенствовать наш скрипт для комментариев на сайте.

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

Наверняка Вы видели, что на многих сайтах при регистрации или добавлении комментариев на странице, кроме имени пользователя, пароля и прочей информации, требуется дополнительно ввести специальный код, отображённый рядом на картинке. Этот код и называется «капча» (или - "каптча").

Зачем это нужно? Для защиты от спаммеров.

Ведь кто-то может написать программу, которая автоматически регистрируется на сайте, причём делает это не один, а несколько десятков или даже сотен раз! Каждая такая запись занимает место, а между тем, дисковое пространство, отведенное нашему сайту хостером, «не резиновое». Да и зачем нам разгребать завалы совершенно ненужной информации?! Поэтому от таких спамм-атак нужно уметь защищаться.

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

Однако надёжней, когда цифры при каждой загрузке страницы разные. Да и выглядит такая каптча солидней.

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

Скачайте архив со скриптами каптчи на свой компьютер, распакуйте в отдельную папку. В архиве два файла: image.php и reg.php. Откройте их в своём редакторе, а также откройте файл, в котором Вы создавали скрипт и форму для добавления комментариев на страницу.

В image.php такой код:

Листинг 1.

<?php
// Генерируем номер
$number = rand('111111','999999');

// Устанавливаем Cookies
setcookie('A_num', $number);

// Создаем рисунок с размером 50x25
$img = imagecreate('50', '25');

// Цвет фона - белый
$back = imagecolorallocate($img, 255, 255, 255);

// Цвет шрифта
$black = imagecolorallocate($img, 0, 0, 0);

// Рисуем цифры
// $img - идентификатор картинки
// 3 - номер шрифта
// 5 - координата X
// 4 - координата Y
// $number - наше число
// $black - цвет шрифта

imagestring($img, 3, 5, 4, $number, $black);
// Выводим рисунок в браузер

imagepng($img);
?>

Важно! Этот файл поместите в одну директорию с той страницей, на которой форма для комментариев!

В reg.php код такой:

Листинг 2.

<?php

// Если форма не отправлена, то выводим ее
if(!isset($number))
{
echo "<FORM action=login.php method=post>
<p>Введите число <INPUT type=text name=number>
<p><img height=25 src=image.php width=50 border=0><br>

<INPUT type=submit name=go value=Проверить>
</FORM>";
} else {
// проверяем введенный код
if(!is_numeric($_POST["number"]))
{
die("Неправильный формат кода!");
}
// Проверка на правильность кода
if($_COOKIE['A_num']!==$_POST["number"])
echo "Код не совпадает!";
else
echo "Код правильный!";

}
?>

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

Моя же задача - соединить эти скрипты со скриптом для добавления комментариев, который мы рассматривали на протяжении тринадцати статей (начиная отсюда).

Причём, скачанные скрипты - лишь исходники, из которых мы будем брать отдельные фрагменты. Я взял эти скрипты из книги "Профессиональное программирование на РНР"...

Хочу сказать, что пользоваться готовыми скриптами - нормально; в Сети можно найти сотни или тысячи библиотек как целых скриптов так и отдельных функций. Просто, если кто-то решил освоить программирование, нужно уметь разбираться в этом готовом, постоянно анализировать чужой код, чтобы потом уже уметь создавать собственные шедевры. Это очень похоже на умение писать книги: сначала будущий автор много читает, анализирует чужие произведения, упражняется в написании простеньких вещиц... и только спустя время обретает способность создавать что-то действительно стОящее.

Сначала внесём изменения в форму для комментариев. Код формы выглядит так:

Листинг 3.

...
<form action="" method="post">
<p>  <label> Ваше имя<font color="#FF0000">* </font>:</label> <br>
<input type="text" name="name"></p>
<p>  <label>E-mail: </label><br>
<input type="text" name="email"></p>
<p>  <label>Сообщение <font color="#FF0000">* </font>:<br>
<textarea name="text" cols="40" rows="5"></textarea></label></p>
<p>Введите сумму чисел с картинки <font color="#FF0000">* </font>:<br>
<input name="summa" type="text" size="10" maxlength="5"><img src="images/sum.gif" width="80" height="50" border="1"></p>

<p><input type="submit" value="Добавить комментарий"></p>
</form>
<?php
$url = "http://comment" .$PHP_SELF;
include ("comments.php");
?>
...

Выделенное красным в Листинге 3 заменяем зелёным фрагментом из Листинга 2, причём я этот фрагмент сразу несколько подредактировал, вот, что получилось:

Листинг 4.

...
<form action="" method="post">
<p>  <label> Ваше имя<font color="#FF0000">* </font>:</label> <br>
<input type="text" name="name"></p>
<p>  <label>E-mail: </label><br>
<input type="text" name="email"></p>
<p>  <label>Сообщение <font color="#FF0000">* </font>:<br>
<textarea name="text" cols="40" rows="5"></textarea></label></p>
<p>Введите цифровой код с картинки <font color="#FF0000">* </font>:<br>
<INPUT type='text' name='number'> <img height='50' src='image.php' width='100' border='0'></p>

<p><input type="submit" value="Добавить комментарий"></p>
</form>
<?php
$url = "http://comment" .$PHP_SELF;
include ("comments.php");
?>
...

Очередь за скриптом-обработчиком формы, который, если мне память не изменяет, у нас в файле comments.php. На сей день он выглядит так:

Листинг 5.

<?php
error_reporting (0);
$gbpath = "gb/gb.dat";

if(getenv("REQUEST_METHOD")=="POST")

{

if (isset ($_POST['name']))
{
$name = $_POST['name'];
}

if (isset ($_POST['email']))
{
$email = $_POST['email'];
}

if (isset ($_POST['text']))
{
$text = $_POST['text'];
}

if (isset ($_POST['summa']))
{
$summa = $_POST['summa'];
}

if (empty ($name) or empty ($email) or empty ($text))
{
echo "Форма заполнена не полностью!";
exit ();
}
if ($summa != 17)
{
echo "Сумма чисел с картинки указана не правильно!";
exit ();
}

else
{


$name = trim ($name);
$email = trim ($email);
$text = trim ($text);

$text = strip_tags ($text);
$email = strip_tags ($email);
$name = strip_tags ($name);

$text = htmlspecialchars ($text);
$email = htmlspecialchars ($email);
$name = htmlspecialchars ($name);

if(!file_exists($gbpath))
{

$f=fopen($gbpath,"w") or die ("Не могу создать файл");
flock($f,2) or die("Невозможно заблокировать файл");
fwrite ($f,"",0);
@chmod($f, 0664);
fclose($f);
}


$f=fopen($gbpath,"r") or die("Не могу открыть файл");
$oldData = fread($f, filesize ($gbpath));
fclose($f);

$f=fopen($gbpath,"w+") or die("Не могу открыть файл");
flock($f,2) or die("Невозможно заблокировать файл");
$date = date("d-m-Y");
$time = time ();
$H = date ('H', $time);
$i = date ('i', $time);
fputs($f, "$url\n");
fputs($f,"$name\n");
fputs($f,"$email\n");
$text=ereg_replace("\n"," ",$text);
fputs($f,"$text\n");
fputs ($f, "$date\n");
fputs ($f, "$H\n");
fputs ($f, "$i\n");
$address = "адрес вашей почты";
$subject = "Новый комментарий на сайте";


$message = "Появился комментарий на странице - " .$url. "\nКомментарий добавил(а): ".$name."\nАдрес почты: " .$email. "\nТекст комментария: ".$text."\nСсылка на заметку: ".$url;


mail ($address, $subject, $message, "Content-type:text/plain; Charset=windows-1251\r\n");

fwrite($f,$oldData);
fclose($f);
}
}
if(file_exists($gbpath))
{
$f=fopen($gbpath,"r") or die("Не могу открыть файл");
while(1){

$url = fgets($f, 1000);
$tmp = trim(str_replace("\n", "", $url));

$name=fgets($f,1000);
$email=fgets($f,1000);
$text=fgets($f,1000);
$date = fgets($f, 1000);
$H = fgets($f, 1000);
$i = fgets($f, 1000);
if(feof($f)) break;

if ($tmp == "http://comment" .$PHP_SELF)
{

echo "<hr>Автор:<a href=mailto:$email>$name</a><br>";
echo $date. "<br>";
echo $H. " час. " .$i. " мин.<br / >";
echo "Сообщение:<br>$text<br>";
}
}
fclose($f);
}
?>

Подправить нужно тот фрагмент, где проверяется сумма, а также изменить название переменной summa на number(выделено красным).

Пользуясь файлом reg.php из Листинга 2, я "сотворил" следующее (кое-что ещё добавив от себя):

Листинг 6.

<?php
error_reporting (0);
$gbpath = "gb/gb.dat";

if(getenv("REQUEST_METHOD")=="POST")

{

if (isset ($_POST['name']))
{
$name = $_POST['name'];
}

if (isset ($_POST['email']))
{
$email = $_POST['email'];
}

if (isset ($_POST['text']))
{
$text = $_POST['text'];
}

if (isset ($_POST['number']))
{
$number = $_POST['number'];
}

if (empty ($name) or empty ($email) or empty ($text))
{
echo "Форма заполнена не полностью!";
exit ();
}

// проверяем введенный код
if(!is_numeric($number)) // проверяем, является ли введённая информация числом, ведь могли бы ввести и текст или код программы
{
die("Неправильный формат кода!");
exit();
}
// Проверка на правильность кода
if($number != $_COOKIE['A_num']) //здесь сравнивается код, введённый пользователем в поле формы с кодом, находящемся в "куках"
{
echo "Код не совпадает!";
exit();
}


$name = trim ($name);
$email = trim ($email);
$text = trim ($text);

$text = strip_tags ($text);
$email = strip_tags ($email);
$name = strip_tags ($name);

$text = htmlspecialchars ($text);
$email = htmlspecialchars ($email);
$name = htmlspecialchars ($name);

if(!file_exists($gbpath))
{
$f=fopen($gbpath,"w") or die ("Не могу создать файл");
flock($f,2) or die("Невозможно заблокировать файл");
fwrite ($f,"",0);
@chmod($f, 0664);
fclose($f);
}


$f=fopen($gbpath,"r") or die("Не могу открыть файл");
$oldData = fread($f, filesize ($gbpath));
fclose($f);

$f=fopen($gbpath,"w+") or die("Не могу открыть файл");
flock($f,2) or die("Невозможно заблокировать файл");
$date = date("d-m-Y");
$time = time ();
$H = date ('H', $time);
$i = date ('i', $time);
fputs($f, "$url\n");
fputs($f,"$name\n");
fputs($f,"$email\n");
$text=ereg_replace("\n"," ",$text);
fputs($f,"$text\n");
fputs ($f, "$date\n");
fputs ($f, "$H\n");
fputs ($f, "$i\n");
$address = "адрес вашей почты";
$subject = "Новый комментарий на сайте";

$message = "Появился комментарий на странице - " .$url. "\nКомментарий добавил(а): ".$name."\nАдрес почты: " .$email. "\nТекст комментария: ".$text."\nСсылка на заметку: ".$url;

mail ($address, $subject, $message, "Content-type:text/plain; Charset=windows-1251\r\n");

fwrite($f,$oldData);
fclose($f);

}

if(file_exists($gbpath))
{
$f=fopen($gbpath,"r") or die("Не могу открыть файл");
while(1){

$url = fgets($f, 1000);
$tmp = trim(str_replace("\n", "", $url));

$name=fgets($f,1000);
$email=fgets($f,1000);
$text=fgets($f,1000);
$date = fgets($f, 1000);
$H = fgets($f, 1000);
$i = fgets($f, 1000);
if(feof($f)) break;

if ($tmp == "http://comment" .$PHP_SELF)
{

echo "<hr>Автор:<a href=mailto:$email>$name</a><br>";
echo $date. "<br>";
echo $H. " час. " .$i. " мин.<br / >";
echo "Сообщение:<br>$text<br>";
}
}
fclose($f);
}
?>

Вот, по-моему, и всё. Осталось сохранить изменения и проверить работу нового скрипта.

Успехов.

P. S. Да, чуть не забыл: вот этот код под формой для комментариев

<?php
$url = "http://comment" .$PHP_SELF;
include ("comments.php");
?>

можно (а может, и лучше будет) поместить перед формой. Попробуйте, сравните результат, возьмите себе, что понравится и...

...в следующую статью.

Автор: Андрей Чернобай

P. S. Подпишитесь на безплатную рассылку Вокруг Сайта и получайте на свой электронный адрес новые уроки по созданию сайта.

Оставьте свой отзыв о статье:



Введите цифровой код с картинки*:


Комментарий добавил(а): Максим
14-09-2012
13 час. 58 мин.

Комментарий:
а можно сделать так, чтобы сведения об ошибке были в другом окне от комментариев

Ответ: Если это вопрос, то ответ да (просто в конце Вашего предложения нет вопросительного знака).


Комментарий добавил(а): Максим
15-09-2012
12 час. 13 мин.

Комментарий:
А как это сделать? просто я в php новичок.

Ответ: Здравствуйте, Максим. Сегодня я добавил новый урок по этому скрипту (http://vokrug-saita.ru/php_comment_next_17.php), посмотрите его, приведите скрипт в соответствии с последними изменениями, а я пока подготовлю ответ на Ваш вопрос.


Комментарий добавил(а): Kakusei
20-10-2012
20 час. 10 мин.

Комментарий:
Здравствуйте.Хочу поинтересоваться, можно-ли проверить работу отправки комментариев без регистрации сайта?

Ответ: Здравствуйте. Не понял, о какой регистрации и какого сайта речь?


Комментарий добавил(а): Оксана
22-10-2012
15 час. 46 мин.

Комментарий:
У меня не работает код. Получается мы куки создаем в середине кода страницы. Куки обязаны быть отправлены до любых других шапок/headers (это ограничение кук, а не РНР). Это требует, чтобы вы помещали вызовы этой функции перед тэгами или . Может дело в этом?

Ответ: Здравствуйте, Оксана. Может быть, вы и правы. Хотя у меня в таком виде скрипт был установлен на сайте в течение долгого времени и работал исправно. Впрочем, и в нынешней версии скрипта картинка-капча подключается в форме (а где ж она ещё может подключаться?), так что и куки устанавливаются с вызовом файла image.php. Тогда, пожалуй, дело не в этом. Мне, наверное, проще было бы ответить на ваш вопрос, если бы вы уточнили, что значит код не работает: вылезает какое-то сообщение об ошибке? или не появляются комментарии? или просто пустая страница? или что-нибудь ещё?


Комментарий добавил(а): Оксана
23-10-2012
15 час. 30 мин.

Комментарий:
Нет, так все работает, только куки пустые, не определяются.

Ответ: А файл image.php в той же директории, где страница, на которой форма для комментариев? Я сначала поместил image.php в папку со скриптом (файл скрипта в отдельной папке), в этом случае каптча выводилась, но цифры в ней не изменялись при обновлении страницы. Потом один из посетителей на это указал, методом проб выяснилось, что этот файл не работает, когда он в другой папке, чем страница с формой. Но, возможно, есть ещё какие-то замороки, так что обратите внимание на местоположение image.php, - там ли он? - и, возможно, стОит поэкспериментировать с его расположением (я ведь просто не знаю структуры вашего сайта). Куки браузером разрешены? Кстати, если всё работает, то как влияет то, что куки пустые?

Новое на сайте

Другие статьи...

Видеокурсы

Рассылки

"Вокруг Сайта"
подпишитесь и получайте на свой e-mail уроки, книги, статьи, скрипты, а также подарки и скидки на товары, продаваемые с сайта

SmartResponder.ru
Ваше имя: *
Ваш e-mail: *

"PHP-песочница"
- PHP для начинающих: уроки с подробным анализом скриптов, необходимых для вашего сайта:

PHP-песочница
Подписаться письмом

Разделы Сайта