Хотя есть части этого ответа, которые относятся только к использованию самой mail()
функции, многие из этих шагов по устранению неполадок могут быть применены к любой почтовой системе PHP.
Существует множество причин, по которым ваш скрипт не отправляет электронные письма. Это трудно диагностировать, если нет явной синтаксической ошибки. Без него вам нужно пройти через контрольный список ниже, чтобы найти возможные потенциальные подводные камни, с которыми вы можете столкнуться.
Убедитесь, что отчеты об ошибках включены и настроены для отчета обо всех ошибках
Отчеты об ошибках важны для устранения ошибок в вашем коде и общих ошибок, с которыми сталкивается PHP. Отчеты об ошибках должны быть включены для получения этих ошибок. Размещение следующего кода в верхней части ваших файлов PHP (или в главном файле конфигурации) включит создание отчетов об ошибках.
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
Смотрите Как я могу получить полезные сообщения об ошибках в PHP? - этот ответ для более подробной информации по этому вопросу.
Убедитесь, что mail()
функция вызывается
Это может показаться глупым, но распространенная ошибка заключается в том, чтобы забыть поместить mail()
функцию в ваш код. Убедитесь, что он там и не закомментирован.
Убедитесь, что mail()
функция вызывается правильно
bool mail (строка $ to, строка $ subject, строка $ message [, строка $ extra_headers [, строка $ extra_parameters]])
Функция mail принимает три обязательных параметра и, необязательно, четвертый и пятый. Если ваш вызов mail()
не имеет хотя бы трех параметров, он потерпит неудачу.
Если ваш вызов mail()
не имеет правильных параметров в правильном порядке, он также потерпит неудачу.
Проверьте почтовые журналы сервера
Ваш веб-сервер должен регистрировать все попытки отправить электронную почту через него. Расположение этих журналов может отличаться (вам может потребоваться узнать у администратора сервера, где они находятся), но их обычно можно найти в корневом каталоге пользователя в logs
. Внутри будут сообщения об ошибках, о которых сообщал сервер, если таковые имеются, связанные с вашими попытками отправить электронную почту.
Проверьте, нет ли соединения с портом
Блокировка порта является очень распространенной проблемой, с которой сталкивается большинство разработчиков при интеграции своего кода для доставки электронной почты с использованием SMTP. И это можно легко отследить в почтовых журналах сервера (местоположение сервера почтового журнала может варьироваться от сервера к серверу, как объяснено выше). Если вы находитесь на сервере общего хостинга, порты 25 и 587 остаются заблокированными по умолчанию. Этот блок специально сделан вашим хостинг-провайдером. Это верно даже для некоторых выделенных серверов. Когда эти порты заблокированы, попробуйте подключиться через порт 2525. Если вы обнаружите, что этот порт также заблокирован, то единственное решение - связаться с вашим хостинг-провайдером, чтобы разблокировать эти порты.
Большинство провайдеров хостинга блокируют эти порты электронной почты, чтобы защитить свою сеть от отправки спам-писем.
Используйте порты 25 или 587 для простых соединений / TLS и порт 465 для соединений SSL. Для большинства пользователей предлагается использовать порт 587, чтобы избежать ограничений скорости, установленных некоторыми хостинг-провайдерами.
Не используйте оператор подавления ошибок
Когда оператор подавления ошибок @
добавляется к выражению в PHP, любые сообщения об ошибках, которые могут быть сгенерированы этим выражением, будут игнорироваться. Существуют обстоятельства, когда использование этого оператора необходимо, но отправка почты не входит в их число.
Если ваш код содержит, @mail(...)
то вы можете скрывать важные сообщения об ошибках, которые помогут вам отладить это. Удалите @
и посмотрите, нет ли сообщений об ошибках.
Рекомендуется только тогда, когда вы проверяетеerror_get_last()
сразу же на предмет конкретных сбоев.
Проверьте mail()
возвращаемое значение
mail()
Функция:
Возвращает, TRUE
если почта была успешно принята для доставки, в FALSE
противном случае. Важно отметить, что только то, что почта была принята для доставки, НЕ означает, что почта действительно достигнет назначенного пункта назначения.
Это важно отметить, потому что:
- Если вы получаете
FALSE
возвращаемое значение, вы знаете, что ошибка заключается в том, что ваш сервер принимает вашу почту. Вероятно, это не проблема кодирования, а проблема конфигурации сервера. Вам нужно поговорить с системным администратором, чтобы узнать, почему это происходит.
- Если вы получаете
TRUE
возвращаемое значение, это не значит, что ваше письмо обязательно будет отправлено. Это просто означает, что письмо было успешно отправлено соответствующему обработчику на сервере PHP. Еще больше точек сбоя вне контроля PHP, которые могут привести к тому, что письмо не будет отправлено.
Таким образом, FALSE
это поможет направить вас в правильном направлении, в то время TRUE
как не обязательно означает, что ваше письмо было успешно отправлено. Это важно отметить!
Убедитесь, что ваш хостинг-провайдер позволяет отправлять электронную почту и не ограничивает отправку почты
Многие совместно используемые веб-хостинги, особенно поставщики бесплатных веб-хостингов, либо не разрешают отправлять электронные письма со своих серверов, либо ограничивают объем, который можно отправлять в течение любого заданного периода времени. Это связано с их усилиями по ограничению использования спамерами более дешевых услуг.
Если вы считаете, что ваш хост имеет ограничения по электронной почте или блокирует отправку электронной почты, проверьте их часто задаваемые вопросы, чтобы увидеть, если они перечисляют какие-либо такие ограничения. В противном случае вам может потребоваться обратиться в службу поддержки, чтобы проверить, существуют ли какие-либо ограничения в отношении отправки электронных писем.
Проверять папки со спамом; запретить помечать письма как спам
Часто по разным причинам электронные письма, отправляемые через PHP (и другие серверные языки программирования), попадают в папку спама получателя. Всегда проверяйте это перед устранением неисправностей вашего кода.
Чтобы не отправлять почту, отправляемую через PHP, в папку спама получателя, вы можете делать разные вещи, как в коде PHP, так и в других случаях, чтобы свести к минимуму вероятность того, что ваши письма будут помечены как спам. Хорошие советы от Michiel de Mare включают в себя:
- Используйте методы аутентификации электронной почты, такие как SPF и DKIM, чтобы доказать, что ваши электронные письма и ваше доменное имя принадлежат друг другу, и предотвратить подделку вашего доменного имени. На веб-сайте SPF есть мастер для создания информации DNS для вашего сайта.
- Проверьте ваш обратный DNS , чтобы убедиться , что IP - адрес почтового сервера точек на имя домена , который используется для отправки почты.
- Убедитесь, что используемый вами IP-адрес отсутствует в черном списке
- Убедитесь, что адрес для ответа является действительным, существующим адресом.
- Используйте полное, настоящее имя адресата в поле «Кому», а не только адрес электронной почты (например
"John Smith" <john@blacksmiths-international.com>
).
- Следите за своими учетными записями о злоупотреблениях, такими как abuse@yourdomain.com и postmaster@yourdomain.com. Это означает - убедитесь, что эти учетные записи существуют, прочитайте то, что им отправлено, и действуйте по жалобам.
- Наконец, сделайте так, чтобы отписаться было действительно легко. В противном случае ваши пользователи откажутся от подписки, нажав кнопку спама , и это повлияет на вашу репутацию.
См. Как убедиться, что электронная почта, которую вы отправляете программно, не помечается как спам? больше на эту тему.
Убедитесь, что все почтовые заголовки поставляются
Некоторые спам-программы отклоняют почту, если в ней отсутствуют общие заголовки, такие как «От» и «Ответить»:
$headers = array("From: from@example.com",
"Reply-To: replyto@example.com",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
Убедитесь, что заголовки почты не имеют синтаксических ошибок
Недействительные заголовки так же плохи, как и отсутствие заголовков. Один неверный символ может быть все, что нужно, чтобы сорвать вашу электронную почту. Перепроверьте, чтобы убедиться, что ваш синтаксис правильный, так как PHP не поймает эти ошибки за вас.
$headers = array("From from@example.com", // missing colon
"Reply To: replyto@example.com", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
Не используйте поддельного From:
отправителя
Хотя в письме должен быть отправитель From :, вы не можете просто использовать какое-либо значение. В частности, адреса отправителей, отправленных пользователями, являются надежным способом заблокировать почту:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Причина: ваш веб-сервер или почтовый сервер не занесен в белый список SPF / DKIM, чтобы притворяться ответственным за адреса @hotmail или @gmail. Он может даже молча отбрасывать письма с From:
доменами отправителей, для которых он не настроен.
Убедитесь в правильности значения получателя
Иногда проблема так же проста, как неправильное значение для получателя письма. Это может быть связано с использованием неверной переменной.
$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
Другой способ проверить это - жестко закодировать значение получателя в mail()
вызов функции:
mail('user@example.com', $subject, $message, $headers);
Это может относиться ко всем mail()
параметрам.
Отправить на несколько аккаунтов
Чтобы исключить проблемы с учетной записью электронной почты, отправьте свою электронную почту на несколько учетных записей электронной почты у разных поставщиков электронной почты . Если ваши электронные письма не поступают на учетную запись Gmail пользователя, отправьте те же электронные письма на учетную запись Yahoo, Hotmail и обычную учетную запись POP3 (например, на учетную запись электронной почты, предоставленную интернет-провайдером).
Если электронные письма поступают на все или на некоторые другие учетные записи электронной почты, вы знаете, что ваш код отправляет электронные письма, но вполне вероятно, что поставщик учетной записи электронной почты по какой-то причине блокирует их. Если электронная почта не поступает ни в одну учетную запись электронной почты, проблема, скорее всего, связана с вашим кодом.
Убедитесь, что код соответствует методу формы
Если вы установили для своего метода формы значение POST
, убедитесь, что вы используете его $_POST
для поиска значений формы. Если вы установили GET
или не установили его вообще, убедитесь, что вы используете его $_GET
для поиска значений формы.
Убедитесь, что action
значение вашей формы указывает на правильное местоположение
Убедитесь, что ваш action
атрибут формы содержит значение, которое указывает на ваш почтовый код PHP.
<form action="send_email.php" method="POST">
Убедитесь, что веб-хостинг поддерживает отправку электронной почты
Некоторые провайдеры веб-хостинга не разрешают или не разрешают отправку электронной почты через свои серверы. Причины этого могут быть разными, но если они отключили отправку почты, вам нужно будет использовать альтернативный метод, который использует третье лицо для отправки этих писем за вас.
В электронном письме к их технической поддержке (после посещения их онлайн-поддержки или FAQ) должно быть указано, доступны ли возможности электронной почты на вашем сервере.
Убедитесь, что localhost
почтовый сервер настроен
Если вы разрабатываете на своей локальной рабочей станции с использованием WAMP, MAMP или XAMPP, сервер электронной почты, вероятно, не установлен на вашей рабочей станции. Без такового PHP не может отправлять почту по умолчанию.
Вы можете преодолеть это, установив базовый почтовый сервер. Для Windows вы можете использовать бесплатную Mercury Mail .
Вы также можете использовать SMTP для отправки ваших писем. Посмотрите этот замечательный ответ от Викаса Двиведи, чтобы узнать, как это сделать.
Включить PHP на заказ mail.log
В дополнение к вашему журналу MTA и PHP, вы можете включить ведение журнала специально для этой mail()
функции . Он не записывает полное взаимодействие SMTP, но, по крайней мере, параметры вызова функции и сценарий вызова.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
Смотрите http://php.net/manual/en/mail.configuration.php для деталей. (Лучше всего включить эти опции в php.ini
или .user.ini
или, .htaccess
возможно.)
Проверьте с помощью службы тестирования почты
Существуют различные службы доставки и проверки на спам, которые вы можете использовать для проверки настроек MTA / веб-сервера. Как правило, вы отправляете почтовое исследование по адресу: их адрес, затем получаете отчет о доставке и более конкретные сбои или анализ позже:
Используйте другой почтовик
Встроенная mail()
функция PHP удобна и часто выполняет свою работу, но имеет свои недостатки . К счастью, есть альтернативы, которые предлагают больше мощности и гибкости, включая решение многих проблем, описанных выше:
Все это можно сочетать с профессиональным SMTP-сервером / поставщиком услуг. (Поскольку типичные планы общего веб-хостинга 08/15 ударились или пропали, когда дело доходит до настройки / конфигурирования электронной почты.)