Всем привет! Добро пожаловать на Блог RS! Сегодня, как я и обещал ранее, мы с Вами займемся разработкой капчи для нашего блога. Что такое капча? Я думаю Вы все видели эти ужасные картинки с непонятными буквами, которые приходятся вводить перед регистрацией или отправкой сообщения. Для чего они? Они помогают отсеять автоматическую регистрацию на сайтах, отсылку автоматических комментарий на блогах. В общем это такая штука, которая не должна мешать обычному пользователю комментировать посты/регистрироваться на сайте, но должна отсеивать всяких роботов которые хотят за спамить Ваш проект!
Проблема в том, что самый действенный способ отсеять автоматический спам, это капча с буковками. Но она в 99% случаев отсеивает не только роботов, но и пользователей. Поэтому программисты придумывали альтернативу буквенной капчи. На моем блоге поначалу была именно буквенная преграда от спам ботов
Сейчас же стоит "клик по картинке"
Мы будем создавать с Вами второй вариант защиты от спам ботов. Давайте для начала определим цель на сегодня.
Для начала Вам понадобятся изображения для нашей защиты от спама. Содержимое архива необходимо скопировать в пользовательскую папку img.
Капча будет выглядеть вот так
Кстати, хочу заметить, что эти фрукты рисовал не я. Изображения взяты с сайта findicons.com
Так же хочу заметить, что если Вы на блоге в первый раз, то этот пост может показаться Вам пустой тратой времени, так как, эта статья, как и многие другие на моем блоге, являются продолжением цикла статей "Создать блог с нуля"
Если Вам интересна эта информация и блог в целом, то подпишитесь на RSS ленту блога через ридер, или же по почте
Я Вам выложу лишь html код самой капчи. Поместить этот код необходимо сразу после большого текстового поля textarea
<p style="margin:0px;">Если вы человек, то нажмите на картинку "<span style="font-weight:bold;">[_q]</span>"</p>
<br>
<input id="code_comm" name="code_comm" type="hidden" value="">
<table width="160px" height="40px" cellpadding="0" cellspacing="0" border="0px">
<tr>
<td>
<img id="cp1OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(1,'[_code0]');" src="[_img0]" border="0px">
</td>
<td>
<img id="cp2OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(2,'[_code1]');" src="[_img1]" border="0px">
</td>
<td>
<img id="cp3OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(3,'[_code2]');" src="[_img2]" border="0px">
</td>
<td>
<img id="cp4OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(4,'[_code3]');" src="[_img3]" border="0px">
</td>
</tr>
</table>
Что мы тут имеем?
Вводится этот ответ будет с помощью функции JS, которая будет срабатывать от нажатие по картинке
Надеюсь, у Вас не составит труда, разобраться в этом коде
Суть модуля очень проста. Необходимо составить массив который будет содержать в себе четыре ссылки на изображения, четыре кода в обычном виде и зашифрованном. Также в этом массиве будет содержаться название фрукта, и другая техническая информация
Использовать будем не обычный массив, а многомерный. Многомерный массив отличается от обычного тем, что каждый элемент массива содержит не просто данные ( текст или цифру ) а еще один массив. Что бы Вы не запутались, я приведу Вам пример многомерного массива нашего модуля на схеме ниже. Схема будет содержать сразу реальный пример, для наглядности.
Есть массив cods у него 4 элемента.
Элементы n.1 помогают нам каждый раз менять порядок вывода изображения. В данном примере картинки и вопрос будут выглядеть вот так
Теперь я дам Вам полностью за комментированный код модуля.
<?php
function capcha()
{
//Вопросы
$q[0] = "Ананас";
$q[1] = "Бананы";
$q[2] = "Арбуз";
$q[3] = "Яблоко";
//Изображния
$imgq[0] = "img/cap1cha.jpg";//ананас
$imgq[1] = "img/cap2cha.jpg";//бананы
$imgq[2] = "img/cap3cha.jpg";//арбуз
$imgq[3] = "img/cap4cha.jpg";//яблоко
for ($iall=0;$iall<4;$iall++)//Формирование массива cods("сортировка","не закодированный код","закодированный код","изображение","вопрос","элемент содержит индикатор, правильный ли ответ")
{
for($i=0;$i<8;$i++)//формирование кода из 8 символов
{
$simvol = chr(rand(97,122));//выбираем любой английский символ
$code[$i] = $simvol;//сохраняем в массив
}
$sort = rand(1,100);//определяем позицию картинки в капче (сортировка)
$code = implode("",$code);//склеиваем код из 8-ми символов
$cods[$iall][0] = $sort;//записываем в массив порядок появление картинок (сортировочный номер)
$cods[$iall][1] = $code;//записываем не закодированный код
$code = md5($code);//шифруем код
$cods[$iall][2] = $code;//записываем в массив шифрованный код
$cods[$iall][3] = $imgq[$iall];//записываем в массив изображение
$cods[$iall][4] = $q[$iall];//записываем в массив вопрос
$cods[$iall][5] = "false";//фиксируются что все ответы не правильные, мы еще не выбрали правильный =)
unset($code);//уничтожаем код
}
rsort($cods);//сортируем массив
$truepars = rand(0,3);//выбираем правильный ответ (из 4-х картинок)
$cods[$truepars][5] = "true";//меняем у одного элемента массива индикатор с false на true. Тем самым выбираем элемент массива содержащий правильный код и правильный вопрос
session_start();//открываем сессию
if($_SESSION['code'])unset($_SESSION['code']);//если код в сессии существует то уничтожаем его
$_SESSION['code'] = $cods[$truepars][2];//записываем шифрованный код в сессию
return $cods;
}
?>
Хочу Вам пояснить вот этот маленький кусочек кода
$simvol = chr(rand(97,122));
Функция chr() позволяет выбрать один символ из таблицы ASCII-кодов. В этой таблицы в диапазоне от 97 до 122 находятся все англо буквы. То есть мы с помощью этой функции по одному символу генерируем код из англо букв (пример: htyrfsil)
Надеюсь Вы разобрались Могу лишь добавить, что этот модуль я так и назвал - capcha.php, и поместил в папку с пользовательскими модулями.
В обработчик нам необходимо добавить определитель post переменной
if(isset($_POST['code_comm']))$code_comm = $_POST['code_comm'];
сразу после вот этой строчки
if(isset($_POST['site_comm']))$site_comm = $_POST['site_comm'];
Ну это понятно для чего делается Далее нам нужно создать проверку на правильность кода. Вставляем вот этот код
//проверка кода
if($code_comm != "")//Если поле было заполнено
{
session_start();//открываем сессию
if(md5($code_comm) != $_SESSION['code'])$error_comm .= "Вы выбрали не ту картинку!|";//Если код неправельный
unset($_SESSION['code']);//уничтожаем код
session_destroy();//уничтожаем сессию
}
else $error_comm .= "Вы не подтвердили, что Вы человек|";//если поле не заполнялось
сразу после вот этой строчки
$txt_comm = htmlspecialchars($txt_comm);
Думаю тут объяснять особо ничего не надо. Просто проверяем правильный ли код, если правильный, то все хорошо, в противном же случае выводим сообщение. Проверка происходит почти по той же схеме как и в первой части поста
Тут тоже ничего сложного, и нового. Сразу после скрипта
//Вывод ошибки
...
//Вывод ошибки
Вставляем вот этот код
//капча
include ("moduls/capcha.php");
$cods = capcha();
for($i=0;$i<4;$i++)
{
$form = str_replace("[_code".$i."]",$cods[$i][1],$form);//вставляем 4 кода в форму
$form = str_replace("[_img".$i."]",$cods[$i][3],$form);//вставляем 4 изображения в форму
if($cods[$i][5] == "true")$form = str_replace("[_q]",$cods[$i][4],$form);//вклеиваем вопрос в форму
}
//капча
В этом коде идет подключение модуля капчи, запуск функции, и замена код-слов. Все очень просто! Думаю Вы разберетесь
Осталось добавить маленькую функцию ява скрипта. Я поместил ее в шаблон comm_form.html, в самом верху
<script>
function capcha(v,val)
{
document.getElementById("code_comm").value = "";
for(var i=1;i<=4;i++)document.getElementById("cp"+i+"OK").style.display = "none";
document.getElementById("cp"+v+"OK").style.display = "block";
document.getElementById("code_comm").value = val;
}
</script>
перед строчкой
<p>Оставить комментарий</p>
....
Каков смысл функции? Все очень просто. С начало чистим ответ и делаем все галочки невидимыми. А после, выставляем галочку в нужном месте, и записываем в скрытое поле код. Вот и все
Ну что же, за сегодня Мы создали капчу для нашей формы комментариев, и познакомились поближе с многомерными массивами, с чем я Вас от души и поздравляю
В следующем посте мы скорее всего займемся аватарами для нашего модуля комментариев, так что не "переключайтесь" и подпишитесь на RSS ленту блога через ридер, или же по почте
Если есть какие вопросы, пользуйтесь формой ниже, с удовольствием отвечу на них
Всего Вам наилучшего! У меня все!
Исходник |
Можно конечно попробовать интегрировать собственный скрипт, но для этого необходимо разобраться в работе обработчика движка...
У меня изображения не распознаются как линки, точнее, только последнее изображение выходит как линк, когда новожу курсором, а остальные...ничего. Даже на клики не реагируют.
Не подскажите, где искать ошибку?
За данный процесс отвечает javascript. Именно он, по клику, прячет или показывает зеленую галочку. Проверьте есть ли у изображений галочек (у тега img) атрибут id. Значения атрибута id должны быть следующие:
- cp1OK
- cp2OK
- cp3OK
- cp4OK
Необльшое уточнение: когда я в самом браузере открываю форму comm_form.html, все работает. alert()-ом проверила какя информация отправляется JS функсии capcha(v,val). Все адекватно работает.
А на сервере, как и описала в первом сообщении, только 4-ая картинка определятся как линк. Смотрела Page Source странички, там у всех картинок(cap1cha.jpg, cap2cha.jpg, cap3cha.jpg, cap4cha.jpg) style="cursor:pointer;" ....
Наверное сервер чего-то не понимает ;).
Буду искать. В любом случае, спасибо за ответ
- cp1OK
- cp2OK
- cp3OK
- cp4OK
- Тире
- Подчеркивание
- Пробел
- числа от 0 до 9
- латинские (в нижнем регистре) буквы от a до z
- латинские (в верхнем регистре) буквы от A до Z
- кириллица (в нижнем регистре) от а до я
- кириллица (в верхнем регистре) от А до Я
Если Вы работаете с utf то желательно изменить регулярку вот так:
if(!preg_match("/^[-_0-9a-zA-Zа-яА-ЯёЁиЙ ]+$/su", $author_comm))
$error_comm .= "Не правильный формат поля 'Автор'|";
И ещё вопросик:
между
...
- Подчеркивание
->- Пробел <-
- числа от 0 до 9
...,
пробел для чего (чтобы в поле Автор можно было пробел применять) его вроде нигде нет?