Контекст
Существуют такие службы, как https://mailboxlayer.com/, которые могут определить качество реального почтового ящика перед отправкой любого электронного письма.
Первоначально эта служба проверяет 3 вещи:
- Если существуют записи MX.
- Если почтовый ящик существует.
- Если почтовый ящик является универсальным.
Проблема
Мне нужно программно сделать нечто подобное в PHP.
Расследование
Записи MX
Для записей MX есть следующая PHP функция, которая выполняет эту работу:
getmxrr ( string $hostname , array &$mxhosts [, array &$weight ] ) : bool
, задокументированная здесь: https://www.php.net/manual/en/function.getmxrr.php
За кадром это класс c DNS поиск. Вот пример сеанса:
ubuntu@ip-177-32-4-56:~$ nslookup -q=mx yahoo.com
Server: 172.30.0.2
Address: 172.30.0.2#53
Non-authoritative answer:
yahoo.com mail exchanger = 1 mta7.am0.yahoodns.net.
yahoo.com mail exchanger = 1 mta5.am0.yahoodns.net.
yahoo.com mail exchanger = 1 mta6.am0.yahoodns.net.
Authoritative answers can be found from:
ubuntu@ip-177-32-4-56:~$
Почтовый ящик существует
Для существования почтового ящика мы уже реализовали соединение lnet с SMTP-сервером, отправив EHLO
, отправьте «from», а затем отправьте «to».
В качестве ссылки см. Эту статью: https://www.webdigi.co.uk/blog/2009/how-to-check-if-an-email-address-exists-without-sending-an-email/
Если имя пользователя не существует, большинство SMTP-серверов отвечают с ошибкой 5xx
. Если он существует и отвечает кодом 2xx
, это не означает, что вам удастся отправить электронное письмо (возможно, квота заполнена или что-то в этом роде, но вы существенно уменьшите вероятность отправки глупых писем).
Почтовый ящик является универсальным
Но не все SMTP-серверы отвечают 5xx
на пользователя, которого не существует. Некоторые, например Yahoo, заставят свой SMTP принимать почту на любой случайный адрес ... попробуйте набрать lnet на порт 25 и отправить что-нибудь на my-very-nice-invented-username-with-random-data-58943758346758923467894@yahoo.com, и он сообщит вам 2xx
.
Вот пример сеанса:
ubuntu@ip-177-32-4-56:~$ telnet mta7.am0.yahoodns.net 25
Trying 67.195.204.72...
Connected to mta7.am0.yahoodns.net.
Escape character is '^]'.
220 mtaproxy303.free.mail.bf1.yahoo.com ESMTP ready
EHLO hi
250-mtaproxy303.free.mail.bf1.yahoo.com
250-PIPELINING
250-SIZE 41943040
250-8BITMIME
250 STARTTLS
mail from:<alice@example.com>
250 sender <alice@example.com> ok
rcpt to:<stupid-address-758346758347587859023475890234758902@yahoo.com>
250 recipient <stupid-address-758346758347587859023475890234758902@yahoo.com> ok
quit
221 mta4014.mail.bf1.yahoo.com
Connection closed by foreign host.
ubuntu@ip-177-32-4-56:~$
Возможное решение
Чтобы эмулировать поведение mailboxlayer.com для проверки универсальности, самое большее, что я могу подумать, это сделать двойной тест: Проверьте ожидаемый адрес, а затем протестируйте тот же MX, создав случайную строку, например, такую как sha1.
Если я проверю e07cf4a93e76ce21eb1f76e1a49e1620f767eb5a@yahoo.com
, и он скажет «да», тогда отметьте yahoo.com
как универсальный метод. domain.
Вопрос
Интересно, есть ли более канонический и чистый способ сделать это, кроме открытой идеи.