|
|
|
| Не помню, кто-то спрашивал реальную проверку e-mail адреса, вот выкладываю решение.
//Тут сразу, крупными буквами, для считающих себя особо-одаренными PHP-программистами, напишу:
//ИСПОЛЬЗУЕМЫЕ В СКРИПТЕ ФУНКЦИИ РАБОТАЮТ ТОЛЬКО НА UNIX-о ПОДОБНЫХ ПЛАТФОРМАХ!
//НИКАКИХ МЛИНА ВИНДОВ И ЛОКАЛХОСТОВ, ТЕСТИРУЕТСЯ В ИНЕТЕ НА УНИКСОВОМ ХОСТЕ ПРОВАЙДРА
//(надеюсь, что никто из посетителей данного форума не имеет дорогущего и суперглючного виндового хостинга)
//оговорка на счет локалхостов: если вы действительно крутой админ и ваши ДНС-ы никогда не падают и ресолвят не хуже рипн-а,
//то на счет локалхостов - это не для вас, сорри за недоверие.
//Тут показано как происходит сам вызов проверки e-mail. Откуда вы его берете (e-mail) - вам решать самостоятельно.
//какой e-mail детектим
$string_email="detect_mail@mail.ru";
unset($ret_ar);
//делаем первую проверку
$ret_ar=validate_mail($string_email);
//выводим на экран ответы сервера (можно убрать, если использовать в своем коде внутри)
//вообще в коде самой функции validate_mail(), все значения возвращаемого массива result(), кроме result[0] и result[100],
//можно удалить, или закоментирвоать, они нужны только для наглядного просмотра ответов сервера, чтобы самому
//точно убедиться в наличии запрашиваемого мыла.
foreach($ret_ar as $val){
print $val . "<br>\n";
}
print "<br><br>";
//смотрим что вернулось
if($ret_ar[100] == 50){
//при значении 50 сотого элемента массива ответов, возможны ошибки сокетов, на всякий случай нужно сделать еще одну попытку
print "Нужна еще одна попытка, проверяем снова...<br><br>\n";
unset($ret_ar);
//делаем вторую проверку
$ret_ar=validate_mail($string_email);
//опять выводим на экран ответы сервера (можно убрать, если использовать в своем коде внутри)
foreach($ret_ar as $val){
print $val . "<br>\n";
}
print "<br><br>";
//смотрим что вернулось (уже не смотрим что были ошибки сокетов)
if($ret_ar[0] === true){
//e-mail существует
print "Вердикт: e-mail существует!<br>\n";
}else{
//e-mail не существует
print "Вердикт: e-mail не существует!<br>\n";
}
}elseif($ret_ar[0] === true){
//e-mail существует
print "Вердикт: e-mail существует!<br>\n";
}else{
//e-mail не существует
print "Вердикт: e-mail не существует!<br>\n";
}
}
//сама функция проверки e-mail адреса с действительным подтверждением аккаунта пользователя
//единственной проблеммой остается сервер rambler.ru (и если есть - похожие на него).
//Рамблер очень долго думает при подключении сокета, а ответ о соединени выдает сразу (220) и скрипт думает что уже законектился,
//а Рамблер (с-у-у-.-а-а) продолжает на отправленные команды возвращать запоздалые строки конекта (220)
//(и мы млина, не собираемся ждать пока он разродится и писать для этого парсер принятых строк и учет переданных байтов)
//хотя, если кому надо, то может подправить функцию и добавить эти 5-10 строк со всеми вытекающими отсюда глюками для остальных серверов.
//поэтому по умолчанию (для Рамблера) в такой ситуации, считаем что мыло существует.
//ввиду этого, вам самостоятельно нужно держать список глючных серверов и перед проверкой мылов через эту функцию,
//сначала проверить - не глючный ли сервер указал пользователь для мыла, и потом решать принять его мыло или нет (но уже на глаз без проверки)
function validate_mail($detect_email){
//хост нашего сервера, от которого мы типа посылаем сообщение
//он используется в HELO и в нашем адресе постмастера
//не нужно пытаться подставить сюда не существующий хост, потому, как многие SMTP
//серверы настроены на проверку совпадения этого хоста с реальным именем хоста по IP адресу
//А также, некоторые сервера (набить морду настройщику без размышлений) автоматически отсылают такие IP
//в блок-листы организаций полицаев почты. Поэтому бана схватить на отправку мылов с вашего сервера - как плюнуть.
$my_host=str_replace("www.", "", $_SERVER["HTTP_HOST"]);
//мы говорим почтовому серверу, что отправляем мыло от постмастера нашего сервера (такой аккаунт есть всегда)
$email_from="postmaster@" . $my_host;
//тут будут ответы сервера и нашей функции
$result=array();
//если не передано мыло для проверки вообще (то у вас кривые руки, что передаете функции пустые строки, и вам читать большие буквы вверху, а конкретно - первую строчку)
if(!$detect_email){
$result[0]=false;
$result[1]="Не передан e-mail адрес для проверки!<br>\n";
$result[100]=5; //не передан адрес проверки
return $result;
}
//устанавливаем по умолчанию результат проверки как - мыла не существует.
//Если возникнут не известные сбои, то мыло считается не существующим (можно поменять, если вам нужно считать существующим)
$result[0]=false;
$result[1]="Стартовая установка ответа в отрицательный!<br>\n";
$result[100]=100; //неизвестная ошибка
$result[20]="my_host: " . $my_host . ", проверяем e-mail: " . $detect_email . "<br>\n";
//сначала проверим, а похожа ли переданная строка на e-mail в принципе
if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $detect_email)){
$result[0]=false;
$result[1]=$detect_email . " - не соответствует формату e-mail адреса!<br>\n";
$result[100]=10; //не верный формат адреса проверки
return $result;
}
//выделим отдельно сервер из мыла
list($user_name, $domain_name )=split("@", $detect_email);
//попытаемся получить MX запись для этого сервера
if(getmxrr($domain_name, $mx_host)){
$connect_host=$mx_host[0];
$result[2]="MX запись: " . $mx_host[0] . "<br>\n";
}else{
//не получили запись, и считаем что она совпадает с сервером
$connect_host=$domain_name;
$result[2]="MX запись:" . $domain_name . "<br>\n";
}
$Out="";
$Out1="";
$From="";
$To="";
$Ends="";
//конектимся по сокету на 25 порт сервера
$Connect=fsockopen($connect_host, 25);
if($Connect){
//законектились успешно получаем ответ сервера
$Out=fgets($Connect, 8192);
if(ereg("^22[0-9]{1}[[:space:]]", $Out)){
//если код ответа 220, то соединение установленно и можно посылать команды серверу
fputs($Connect, "HELO " . $my_host . "\r\n");
$Out1=fgets($Connect, 8192);
fputs($Connect, "MAIL FROM: <" . $email_from . ">\r\n");
$From=fgets($Connect, 8192);
fputs($Connect, "RCPT TO: <" . $detect_email . ">\r\n");
$To=fgets($Connect, 8192);
fputs($Connect, "QUIT\r\n");
$Ends=fgets($Connect, 8192);
fclose($Connect);
//проверяем что отвечал нам сервер на наши команды
if(!ereg("^25[0-9]{1}[[:space:]]", $From)){
//SMTP сервер не принял адрес отправителя (пойти и набить морду настройщику этого сервера,
//конечно, если мы сами спамеры и по праву находимся в блок листе - то набить морду нам).
//Других причин быть не может, потому, как postmaster@наш_домен.зона существует всегда и правильный по определению.
$result[0]=false;
$result[1]="Сервер отверг адрес отправителя!<br>\n";
$result[100]=3; //e-mail не определен
}elseif(!ereg("^25[0-9]{1}[[:space:]]", $To)){
//SMTP сервер ответил отрицательно на запрос адреса получателя (может и шифруется сволочь излишне, а может действительно нет такого юзера, тут зависит от того, какой код вернул. Если 550, то юзера скорее всего нет, или пойти набить морду настройщику сервера. Если 551, то возможно сервер запрещает перенаправление от сторонних отправителей без авторизации. Если 552, 553, 554 - то точно юзера нет такого, во всех остальных случаях - фортуна, лотерея.)
$result[0]=false;
$result[1]="Сервер отверг адрес!<br>\n";
$result[100]=2; //e-mail не существует
}else{
//надо же! SMTP сервер подтвердил такое мыло!
$result[0]=true;
$result[1]=$detect_email . " - e-mail существует!<br>\n";
$result[100]=1; //e-mail существует
}
}else{
//конект установился, а на следующую команду ответ не пришел (млина, это точно Рамблер глючный с нами шутит, но на всякий случай нужно повторить определение еще раз).
$result[0]=false;
$result[1]="Не получен ответ на запрос от e-mail сервера!<br>\n";
$result[100]=50; //нужно повтоирть попытку еще раз, возможно просто ошибка сокетов
}
}else{
//конект не установлен по сокету на 25 порт (может и запрет в политике на подключение, пойти и набить морду настройщику).
$result[0]=false;
$result[1]="Не удалось соединиться с e-mail сервером!<br>\n";
$result[100]=50; //нужно повтоирть попытку еще раз, возможно просто ошибка сокетов
}
//тут дописываем в массив ответы сервера для возврата
$result[3]="ответ на Connect сокета: " . $Out . "<br>\n";
$result[4]="ответ на HELO: " . $Out1 . "<br>\n";
$result[5]="ответ на FROM: " . $From . "<br>\n";
$result[6]="ответ на TO: " . $To . "<br>\n";
$result[7]="ответ на QUIT: " . $Ends . "<br>\n";
//вернем массив ответов
return $result;
}
|
| |
|
|
|
|
|
|
|
для: XPraptor
(07.02.2006 в 18:41)
| | 8-0
Зачот :)
Только ИМХО из пушки по воробьям... Обычно хватает подтверждения аккаунта | |
|
|
|
|
|
|
|
для: Axxil
(07.02.2006 в 19:47)
| | ИМХО тоже. Но кто-то спрашивал и хотел именно уверенности что емайл действительно есть и на нег можно послать сообщение. | |
|
|
|
|
|
|
|
для: XPraptor
(08.02.2006 в 01:18)
| | Ага :) ЖЖот скрипт :)))))))) | |
|
|
|
|
|
|
|
для: Гуру
(15.02.2006 в 18:26)
| | А как будет срабатывать, если закрыт доступ с вашего хостинга. Т.е., например, mail.ru закрывает все адреса и открывает только те, которые хочет. Если Вы посылаете со своего адреса, а он у mail.ru числится в "спамерских" и не позволит ни получить запрос, ни отправить ответ, то что будет? | |
|
|
|
|
|
|
|
для: Andrey_V
(15.02.2006 в 22:22)
| | Скриптец зачетный! При хорошо настроенном майл сервере! бесполезен! Так как сервер не дает возможности проверить валидность! Это расценивается как попытка отправки спама. | |
|
|
|
|
автор: Kolobok (20.02.2006 в 09:51) |
|
|
для: XPraptor
(07.02.2006 в 18:41)
| | а чем можно заменить getmxrr? чтобы на винде работало | |
|
|
|
|
|
|
|
для: Kolobok
(20.02.2006 в 09:51)
| | Самой функции на Винде нету, но модно действовать и по другому... | |
|
|
|
|
|
|
|
для: ZC
(20.02.2006 в 13:17)
| | Настройка от спама ни причем. Скрипт делает реальную попытку отправки от реального своего имени (postmaster@host.com).
Все сервера принимают такую почту. Если только сам ваш хост занесен в блоклисты, то вам читать комментарии про "набить морду" (в данном случае вам за спаммерство).
В этом случае, на своих сайтах я считаю что мыла не существует, потому, что зачем мне мыло, на которое я ничего не могу отправить.
На счет замены getmxrr в винде - lockup (млина, не помню как пишется, короче локуп виндовая оболочка для проверки днс-ов) через shell.
У меня класс для отправки e-mail, в котором используется оба варианта и класс сам определяет где он запущен на винде или на unix-овом хосте.
Кстати, я уже доработал этот скрипт и теперь даже глючный рамблер проверяется без проблемм.
В скрипт добавилась проверка хостов из таблицы Glukenmail базы MySQL в которой храним все тормозные с ответом сервера.
Скрипт перед проверкой адреса смотрит эту таблицу и если это глючный хост, то включается специальная процедура, которая лжидает пока все 220-ые ответы не придут после установки соединения.
Также в скрипте включен разбор что именно ответил сервер при отрицательном ответе и функция возвращает разные значения, которые можно проанализировать и сделать вывод что именно не устроило сервер при проверке.
Если кому надо, то могу выложить, но уже приатченным файлом, немного описав саму процедуру проверки. | |
|
|
|
|
автор: Kolonok (21.02.2006 в 01:02) |
|
|
для: XPraptor
(20.02.2006 в 15:22)
| | Конешна выкладывай. Хочется посмотреть реальный пример работы с почтой на деле | |
|
|
|
|