Здравствуй %habrauser%.
Буквально вчера на Хабрахабре был опубликован перевод «Прекратите проверять Email с помощью регулярных выражений!», правильно. Прекратите. Есть способ проверки существования email куда более эффективный.
Если интересно – прошу под кат.
Для начала я попробую объяснить принцип идеи, а она очень проста. Получаем MX запись для домена и пробуем провести диалог с сервером. Просто? Проверим.
Проверку я делал на сервере gmail.
Все нижеописанные действия разворачиваются в консоли, если Вам это не очень интересно — внизу есть рабочий пример на php.
user@server:~# dig MX gmail.com
; <<>> DiG 9.7.3 <<>> MX gmail.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38407
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;gmail.com. IN MX
;; ANSWER SECTION:
gmail.com. 3600 IN MX 10 alt1.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 30 alt3.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 40 alt4.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 20 alt2.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 5 gmail-smtp-in.l.google.com.
;; Query time: 18 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Apr 4 20:24:58 2013
;; MSG SIZE rcvd: 150
Как видим записей много, целых пять штук. Но ничего страшного.
user@server:~# telnet alt1.gmail-smtp-in.l.google.com. 25
Connected to mx.example.com.
220 mx.google.com ESMTP fz8127fd6407obb.42 - gsmtp
Берём первую запись и нам везёт – сервер откликается, соединение установлено.
Не ждём долго, приветствуем и представляемся.
HELO example.com
250 mx.google.com at your service
MAIL FROM: <noreply@example.com>
250 2.1.0 OK fz8127fd6407obb.42 – gsmtp
Замечательно, нас рады видеть и ждут не дождутся, когда мы назовём адресата. Адресата? Да, пожалуйста!
RCPT TO: <abuse@gmail.com>
250 2.1.5 OK fz8127fd6407obb.42 – gsmtp
Всё, гугл рад готов читать ваши абузы и ждёт не дождётся когда вы их отправите. Но нам это не нужно, посему – завершаем сессию.
QUIT
221 2.0.0 closing connection fz8127fd6407obb.42 – gsmtp
Connection closed by foreign host.
user@server:~#
Если адресат не существует, сервер должен вернуть код #550 или #553, если адресат не однозначен. У гугла это выглядит примерно так:
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://support.google.com/mail/bin/answer.py?answer=6596 fz8127fd6407obb.42 – gsmtp
На этом, как не странно – всё. Вот такая достаточно простая процедура позволяет нам узнать о том, не обманул ли нас и не ошибся ли наш драгоценный пользователь.
Пример на php на github.
Подробно про протокол можно почитать тут RFC 5321.
Надеюсь, что этот топик показался Вам полезным. И спасибо Вам, что дочитали до конца.
P.S. Я лично этот способ на продакшене не проверял. И подтвердить его работоспособность, с большим потоком проверок, не могу. Но в теории должно работать без проблем.
P.S.S. Да, может случится так, что пользователь введёт корректный email, но его почтовый сервер в этот момент будет недоступен. Это, действительно, возможный и не очень приятный вариант развития событий. Но и классическое письмо с кодом подтверждения будет валяться в очереди на отправку… если вообще отправится.