Вначале проблема спама не так беспокоила меня, пока однажды горы рекламных писем не посыпались на мой ящик. В этот же день нашёл простой выход: «собачку» можно показывать как картинку, всё остальное – как символы. Внешне – обычный e-mail, а скопировать не получится.Предлагаю вашему вниманию простой и доступный способ публикации e-mail адресов без опасения, что его просканирует спам-робот. Хотя, возможно, и просканирует, но для этого он должен обладать искусственным интеллектом
Требования: наличие PHP с библиотекой GD. Многие наверно догадались, что мы будем делать с адресами. Мы будем их… рисовать! Назовём наш скрипт email.php. Алгоритм достаточно прост:Одним из способов скрипт получает на вход е-mail адрес: Получим адрес автора из базы данных, указав например id статьи или записи в гостевой книге (каталоге файлов, ссылок и т.д.). Передадим адрес скрипту в явном виде: email.php?adr=name@server.ru (но это чревато тем, что e-mail всё-таки «засвечен»). Такая защита равносильна её отсутсвию. Передадим адрес скрипту в неявном виде: email.php?name=name&server=server.ru Передадим адрес скрипту в зашифрованном виде: email.php?adr=anzr@freire.eh (воспользовавшись функцией str_rot13() , которая смещает коды всех латинских букв вверх на 13). Скрипт расшифровывает данные, генерирует картинку с изображением адреса и возвращает её браузеру. Для начала рассмотрим процесс «рисования», так как он впоследствии останется неизменным:$size = 2; $im = imagecreate(imagefontwidth($size)*strlen($adr), imagefontheight($size)); Здесь нет ничего особенного. Исходные данные: $adr – адрес, который надо «нарисовать», $size – размер шрифта на картинке (легко подбирается по размеру и «жирности», внешне похож на Tahoma, Verdana, Arial). Функция imagecreate() создаёт картинку и помещает указатель на неё в переменную $im. Однако для этого вычислим размеры будущей картинки, исходя из размера шрифта и количества символов в строке.imagefontwidth($size) – определяет ширину одного символа при размере $size. Умножим её на длину строки strlen($adr) и получим ширину будущей картинки. Высота картинки вычисляется функцией imagefontheight($size). Добавляем в палитру изображения цвета фона и надписи (соответственно белый и красный)$bg = imagecolorallocate($im, 255, 255, 255); $black = imagecolorallocate($im, 0x00, 0x00, 0x00);Если цвет фона вашего сайта не белый, сделаем так: imagecolortransparent($im,$bg); Цвет $bg в палитре станет прозрачным, поэтому $bg может быть любым цветом. Цвет символов задаётся в соответствии с вашими потребностями.Делаем надпись:imagestring($im, $size, 0, 0, $adr, $black); И выводим картинку : header('Content-type: image/png'); imagepng($im); Теперь рассмотрим, какими способами можно получить e-mail для обработки. В таблице помещены варианты адресации и соответствующие фрагменты кода.Извлечение e-mail из базы данных MySQL.email.php?id=1 mysql_connect("localhost", "username", "password"); mysql_select_db("database"); $id = abs(intval($id)); $query = "SELECT email FROM table WHERE table_id='$id'"; $result = mysql_query ($query); $f = mysql_fetch_array($result); if (empty($f[email])) $adr = "n/a"; else $adr = $f[email]; Прямая передача адресаemail.php?adr=name@server.ru дополнительный код не нуженРаздельная передача адресаemail.php?name=name& server=server.ru $adr = $name.”@”.$server Передача закодированного адресаemail.php?adr=anzr@freire.eh(адрес был закодирован функцией str_rot13(), она же раскодирует его, потому что букв в латинском алфавите всего 26, а смещение каждый раз на 13) $adr = str_rot13($adr); Вот весь скрипт целиком (добавьте нужный вам способ получения адреса): Вывод картинки вместо реального e-mail делается примерно так:Ваш e-mail: name@server.ru Ваш e-mail:
[img]email.php?adr=name@server.ru[/img]
Теперь, когда мы знаем, как заменять e-mail адреса, можно написать функцию, которая будет производить такие замены в заданном тексте при помощи регулярных выражений. Это может потребоваться при тотальной фильтрации всего вывода, пакетной обработке HTML-файлов, выводе информации из БД.Разделим адрес на 3 части:(Имя)@(Домен).(Зона) И того уже имеем паттерн типа:(.*)@(.*).(.*) Под эту формулу подойдут миллиарды выражений, но мы идём дальше по спецификации e-mail адреса. Имя пользователя должно состоять из "a-z", "A-Z", "0-9", а также ".", "_" и "-". Если не ошибаюсь, строгих правил по этому поводу никогда не было, где-то разрешены и другие символы, это основа. "A-Z" добавлено на случай если пользователь любит прописывать своё мыло "покруче". Длина имени от 2-х до 256-ти символов (см. RFC). Дальше домен, тоже самое – "a-z", "A-Z", "0-9", ".", "-" и всё! Длина доменного имени та же, единственная загвоздка – если мыло находится не в домене второго уровня, а, скажем, третьего или даже четвёртого. Тут снова в RFC кидаться надо, поскольку и сама служба DNS не лишена "ответа" типа HTTP 414 :). Длина домена не может превышать 256 символов, но вот входят ли в это число поддомены – не помню. Зона – здесь просто "a-z", "A-Z" от 2-х до 4-х символов.В итоге получается что-то такое:([a-zA-Z0-9|.|-|_]{2,256})@(([a-zA-Z0-9|.|-]{2,256}).([a-z]{2,4})) Можно проверить, не начинаются ли (или заканчиваются) подвыражения \\1, \\2 символами типа "." или "-", дальше – на что фантазии хватает. Используя вычисленное регулярное выражение (невольно вспоминаются лекции по матанализу), напишем функцию, которая будет заменять все адреса e-mail в строке на тэг IMG и возвращать изменённую строку. В качестве функции замены я использовал preg_replace() с синтаксисом Perl RegExp.email_replace.php [img]email.php?name=1&server=2[/img] ', $text); } // исходная строка со множеством e-mail адресов$text =<<Если вы нашли в этой статье спорные или непонятные моменты, жду ваших комментариев. Протестировать и скачать все варианты скриптов можно здесь: http://foxweb.net.ru/test/email/.