#Симптомы, область применения и причины
PHP mail() сообщает об успешной передаче письма локальному обработчику, но не гарантирует доставку адресату. Как проверить очередь MTA, журналы SMTP, DNS и ошибки получателя без отправки секретов. Нужно найти переход, на котором письмо остановилось: PHP → локальный почтовый агент → исходящий SMTP → сервер получателя → почтовый ящик или спам. Успешный вызов mail() подтверждает лишь принятие на отправку.
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Локальный MTA принял письмо и поставил в очередьPHP завершил вызов, но почтовая служба ещё не доставила письмо. | Письмо есть в очереди Postfix/Exim, журнал показывает deferred/timeout. | Посмотреть очередь и сообщение о временной ошибке, не очищать очередь. |
| Удалённый сервер отклонил письмоНе настроены SPF/DKIM/DMARC, не совпадает адрес отправителя или IP имеет плохую репутацию. | В журнале SMTP после отправки указан ответ 5xx или есть уведомление о недоставке. | Исправить точную причину ответа, проверить записи домена и репутацию. |
| Письмо принято, но попало в спам или фильтрПромежуточные фильтры или пользовательские правила изменили папку назначения. | SMTP подтверждает 250 OK, но во «Входящих» письмо отсутствует. | Проверить карантин, «Спам», правила и трассировку у получателя. |
#Безопасная диагностика и пошаговое исправление
- Уточните, что именно возвращает mail()В журнале приложения зафиксируйте время, адрес отправителя, домен получателя и результат вызова
mail()без текста письма, персональных данных и токенов. Важное отличие:trueозначает, что транспорт принял письмо для передачи, а не что оно оказалось в папке «Входящие». Для контрольного теста используйте почтовый ящик, доступный вам, и одно письмо с уникальной темой, а не массовую рассылку.
- Определите почтовый транспорт сервераВ панели хостинга откройте раздел почтовой службы для домена и найдите журнал отправки/очередь. Если у вас собственный Debian/Ubuntu, по SSH проверьте, установлен ли Postfix или Exim и какой MTA принимает сообщения из PHP. Настройка
sendmail_pathв рабочем PHP обычно указывает программу передачи письма.php -iиз терминала может относиться к другому обработчику и не отражать настройки PHP-FPM сайта.
- Посмотрите состояние очереди, ничего не удаляяПри Postfix выполните
sudo postqueue -pпо SSH: команда покажет идентификаторы писем, получателей и причины задержки. Вывод предназначен для администратора, может содержать личные адреса — перед публикацией скрывайте их. Если команда не найдена, не устанавливайте Postfix наугад: на сервере может использоваться Exim или внешний SMTP. Для Exim доступностьexim -bpзависит от установки; пользуйтесь документацией фактической почтовой службы.Linux · Терминал (Bash)КомандаНужен sudoТолько на сервере с Postfix. Просмотр очереди без удаления и принудительной отправки.sudo postqueue -p
- Прочитайте причину в журнале отправкиВ панели откройте журнал исходящих писем или через SSH посмотрите
journalctl -u postfix --since "1 hour ago"для системы с Postfix/systemd. На Debian журнал также может вести/var/log/mail.log. Ищите запись по времени и идентификатору письма:status=sent,status=deferredилиstatus=bounced, ответ сервера и IP узла. Если нет ни очереди, ни записей, проверьте, какой обработчик принял сообщение из PHP и доступен ли он вообще.Linux · Терминал (Bash)КомандаНужен sudoЗапускать в SSH с sudo только при использовании Postfix; журнал может храниться в другом месте.sudo journalctl -u postfix --since "1 hour ago" --no-pager
- Разделите временный отказ и постоянныйSMTP-код 4xx обычно означает временный отказ и ожидание повтора, 5xx — постоянную ошибку. Не очищайте очередь и не запускайте массовые повторы, пока не известна причина. При DNS-ошибках проверьте MX получателя и сетевую доступность на стороне почтового сервера; при ошибке «relay access denied» — разрешённый способ отправки в вашей инфраструктуре. Не пытайтесь обходить запреты провайдера или спам-фильтры.
- Проверьте адрес отправителя и аутентификацию доменаУбедитесь, что заголовок From содержит настоящий адрес на домене, которым вы управляете, а не подставленный чужой. В панели DNS домена посмотрите SPF и DKIM для вашего фактического почтового поставщика; DMARC должен соответствовать политике домена. При использовании внешней рассылки настройте подтверждённую почту и авторизованный SMTP согласно требованиям поставщика. Не придумывайте SPF-записи и не публикуйте ключи DKIM.
- Исключите фильтрацию в почтовом ящикеЕсли удалённый сервер вернул подтверждение принятия, откройте ящик получателя, проверьте «Спам», «Все письма», карантин и правила пересылки. Отправьте контрольное письмо на второй собственный ящик другого домена. Если одно письмо приходит, а другое нет, предоставьте администратору принимающей стороны SMTP-идентификатор и время, а не пароль почты.
- Повторите одиночный тест и зафиксируйте результатПосле точечного исправления MTA, DNS или SMTP отправьте одно новое письмо с уникальной темой, найдите его идентификатор в журнале и убедитесь, что получатель действительно получил его. Если письмо снова зависло, восстановите исходные настройки транспорта из копии и передайте поддержке точный SMTP-код и временную метку. Не меняйте настройки рабочего MTA без сохранённой конфигурации.
#Как проверить результат и что делать дальше
Подтверждение результата — одновременно запись транспорта о доставке/принятии удалённой стороной и фактическое письмо в контрольном ящике. Сам mail()===true этого не подтверждает. Если результата нет, оставьте очередь для диагностики, обратитесь к администратору почты с кодом SMTP и не отключайте SPF/DKIM/DMARC ради теста.