Функция PHP mail не завершает отправку электронной почты


477
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = 'contact@yoursite.com';
    $subject = 'Customer Inquiry';
    $body = "From: $name\n E-Mail: $email\n Message:\n $message";

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $from)) {
            echo '<p>Your message has been sent!</p>';
        } else {
            echo '<p>Something went wrong, go back and try again!</p>';
        }
    }
?>

Я пытался создать простую почтовую форму. Сама форма находится на моей index.htmlстранице, но она отправляется на отдельную страницу «Спасибо за ваше представление» thankyou.php, где встроен указанный выше код PHP. Код отправляет отлично, но никогда не отправляет электронное письмо. Как я могу это исправить?


2
ваша программа на локальном компьютере или в прямом эфире
Тамил Селван C

6
1. Вы уверены, что это не входит в ваш спам? 2. у вас на почтовом ящике настроен sendmail?
Стивен Мозли

это на живом хосте, это не входит в мой спам .. я не уверен, что вы имеете в виду, настроив sendmail на моем ящике, поэтому я предполагаю, что нет?
user3818620

попробуйте отправить без$from
Артем Ильченко

Ответы:


512

Хотя есть части этого ответа, которые относятся только к использованию самой 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 ударились или пропали, когда дело доходит до настройки / конфигурирования электронной почты.)


11
Хорошо написано, Джон. Я хотел бы просто добавить еще одну вещь: проверка журналов почтового сервера отправляющего почтового сервера (будь то локальный или удаленный хостинг), если это возможно, часто может пролить свет на причины проблемы. Эти журналы должны показывать: 1) было ли сообщение получено из сценария PHP отправляющим почтовым сервером и, если да, 2) приняло ли получающее MX сообщение от отправляющего почтового сервера.
mti2935

@ mti2935 Это так полезно, я удивлен, что пропустил это. Я обязательно добавлю это в ближайшее время. :)
Джон Конде

1
я бы начал с не использовать mail(), он делает такую ​​плохую работу и сложнее отлаживать, чем любая другая почтовая библиотека

1
тот же веб-сайт на 000webhost успешно и быстро отправляет электронные письма на домен netai.net, но на site88.net у меня тот же веб-сайт, который я получаю в консоли, и сообщение успешно отправляется, но я не получаю никаких сообщений. Также в домене comuf.com я получаю сообщение об ошибке. (Тот же веб-сайт на том же хосте работает только на домене netai.net, также работает net16.net)
Николас Папаконстантину

1
мой вопрос ( stackoverflow.com/questions/44866673/… ) был помечен как дубликат этого, но я до сих пор не могу понять его. Какие-либо предложения?
Захария Элкинс

37

Добавьте почтовый заголовок в функцию mail:

$header = "From: noreply@example.com\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";

$status = mail($to, $subject, $message, $header);

if($status)
{
    echo '<p>Your mail has been sent!</p>';
} else {
    echo '<p>Something went wrong. Please try again!</p>';
}

25
  1. Всегда пытайтесь отправлять заголовки в функции почты.
  2. Если вы отправляете почту через localhost, тогда настройте SMTP для отправки почты.
  3. Если вы отправляете почту через сервер, убедитесь, что на вашем сервере включена функция отправки электронной почты.

20

Если для отправки электронной почты вы используете конфигурацию SMTP, попробуйте использовать PHPMailer . Вы можете скачать библиотеку с https://github.com/PHPMailer/PHPMailer .

Я создал свою электронную почту, отправляя таким образом:

function send_mail($email, $recipient_name, $message='')
{
    require("phpmailer/class.phpmailer.php");

    $mail = new PHPMailer();

    $mail->CharSet = "utf-8";
    $mail->IsSMTP();                                      // Set mailer to use SMTP
    $mail->Host = "mail.example.com";  // Specify main and backup server
    $mail->SMTPAuth = true;     // Turn on SMTP authentication
    $mail->Username = "myusername";  // SMTP username
    $mail->Password = "p@ssw0rd"; // SMTP password

    $mail->From = "me@walalang.com";
    $mail->FromName = "System-Ad";
    $mail->AddAddress($email, $recipient_name);

    $mail->WordWrap = 50;                                 // Set word wrap to 50 characters
    $mail->IsHTML(true);                                  // Set email format to HTML (true) or plain text (false)

    $mail->Subject = "This is a Sampleenter code here Email";
    $mail->Body    = $message;
    $mail->AltBody = "This is the body in plain text for non-HTML mail clients";
    $mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
    $mail->addAttachment('files/file.xlsx');

    if(!$mail->Send())
    {
       echo "Message could not be sent. <p>";
       echo "Mailer Error: " . $mail->ErrorInfo;
       exit;
    }

    echo "Message has been sent";
}

2
Мне также пришлось использовать: require ("phpmailer / class.smtp.php");
Даг

15

Просто добавьте несколько заголовков перед отправкой почты:

<?php 
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com'; 
$to = 'contact@yoursite.com'; 
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

И еще кое-что. mail()Функция не работает в локальном хосте. Загрузите свой код на сервер и попробуйте.


1
это фактически сделало форму отправкой - мой вопрос теперь будет ... как мне показать пользователя, набранного в электронном письме, теперь, когда я заменил его на заголовок ...
user3818620

это предотвратит почту от спама. Я видел, если мы отправляем почту более 10, используя этот метод, который вы использовали в своем коде Gmail отправлять это письмо в спам.
jewelhuq

У ОП есть такая строка: $from = 'From: yoursite.com'; которая не похожа на полный действительный адрес электронной почты, там нет локальной части. Вы заменили заголовок From и добавили дополнительные. Вернее, $fromвышесказанное в вашем примере излишне. И быть уродливым было, вероятно, оригинальной проблемой ОП.
Progrock

13

Он работал для меня на 000webhost следующим образом:

$headers  = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";

Введите адрес электронной почты непосредственно при отправке электронной почты:

mail('email@gmail.com', $subject, $message, $headers)

Используйте ''и нет "".

Этот код работает, но письмо было получено с задержкой в ​​полчаса.


10

В основном mail()функция отключена на виртуальном хостинге. Лучшим вариантом является использование SMTP. Лучшим вариантом будет Gmail или SendGrid.


SMTPconfig.php

<?php 
    $SmtpServer="smtp.*.*";
    $SmtpPort="2525"; //default
    $SmtpUser="***";
    $SmtpPass="***";
?>

SMTPmail.php

<?php
class SMTPClient
{

    function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
    {

        $this->SmtpServer = $SmtpServer;
        $this->SmtpUser = base64_encode ($SmtpUser);
        $this->SmtpPass = base64_encode ($SmtpPass);
        $this->from = $from;
        $this->to = $to;
        $this->subject = $subject;
        $this->body = $body;

        if ($SmtpPort == "") 
        {
            $this->PortSMTP = 25;
        }
        else
        {
            $this->PortSMTP = $SmtpPort;
        }
    }

    function SendMail ()
    {
        $newLine = "\r\n";
        $headers = "MIME-Version: 1.0" . $newLine;  
        $headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;  

        if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP)) 
        {
            fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n"); 
            $talk["hello"] = fgets ( $SMTPIN, 1024 ); 
            fputs($SMTPIN, "auth login\r\n");
            $talk["res"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpUser."\r\n");
            $talk["user"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpPass."\r\n");
            $talk["pass"]=fgets($SMTPIN,256);
            fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n"); 
            $talk["From"] = fgets ( $SMTPIN, 1024 ); 
            fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n"); 
            $talk["To"] = fgets ($SMTPIN, 1024); 
            fputs($SMTPIN, "DATA\r\n");
            $talk["data"]=fgets( $SMTPIN,1024 );
            fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
            $talk["send"]=fgets($SMTPIN,256);
            //CLOSE CONNECTION AND EXIT ... 
            fputs ($SMTPIN, "QUIT\r\n"); 
            fclose($SMTPIN); 
            // 
        } 
        return $talk;
    } 
}
?>

contact_email.php

<?php 
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
    $to = "";
    $from = $_POST['email'];
    $subject = "Enquiry";
    $body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
    $SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
    $SMTPChat = $SMTPMail->SendMail();
}
?>

Это хорошая идея, чтобы сохранить SMTP-пользователя и пароль в виде открытого текста на сервере?
Юрий

@Juri, вероятно, нет ... Боже, я не могу понять, как заставить работать функцию почты:. (

9

Если вы используете только эту mail()функцию, вам необходимо заполнить файл конфигурации.

Вам нужно открыть почтовое расширение, установить SMTP smtp_portи так далее, и самое главное, ваше имя пользователя и ваш пароль. Без этого почта не может быть отправлена. Также вы можете использовать PHPMailкласс для отправки.


9

Попробуйте эти две вещи по отдельности и вместе:

  1. удалить if($_POST['submit']){}
  2. удалить $from(только моя кишка)

8

Я думаю, что это должно сработать. Я просто добавил if(issetи добавил конкатенацию к переменным в теле, чтобы отделить PHP от HTML.

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = 'contact@yoursite.com'; 
    $subject = 'Customer Inquiry';
    $body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;

if (isset($_POST['submit'])) 
{
    if (mail ($to, $subject, $body, $from)) 
    { 
        echo '<p>Your message has been sent!</p>';
    } 
    else 
    { 
        echo '<p>Something went wrong, go back and try again!</p>'; 
    }
}

?>

8

Для тех, кто считает, что это идет вперед, я бы не рекомендовал использовать mail. Есть некоторые ответы, которые касаются этого, но не причина этого.

mailФункция PHP не только непрозрачна, она полностью зависит от того, какой MTA вы используете (например, Sendmail ) для выполнения работы. mailбудет только сказать вам , если АПС не смог принять его (т.е. Sendmail был вниз , когда вы пытались отправить). Он не может сказать вам, была ли почта успешной, потому что она была передана. Как таковой (как ответ Джона Конде подробности ), теперь вы можете поиграть с журналами MTA и надеяться, что он достаточно расскажет вам о невозможности его исправить. Если вы используете общий хост или не имеете доступа к журналам MTA, вам не повезло. К сожалению, по умолчанию для большинства ванильных установок для Linux это так.

Почтовая библиотека ( PHPMailer , Zend Framework 2+ и т. Д.) Делает нечто очень отличное от mail. Они открывают сокет непосредственно на принимающий почтовый сервер, а затем отправляют SMTP-команды прямо через этот сокет. Другими словами, класс действует как собственный MTA (обратите внимание, что вы можете указать библиотекам использоватьmail для окончательной отправки почты, но я настоятельно рекомендую вам не делать этого).

Это означает, что вы можете сразу увидеть ответы от принимающего сервера (например, в PHPMailer вы можете включить отладочный вывод ). Больше не нужно гадать, не удалось ли отправить письмо или почему.

Если вы используете SMTP (т.е. вы звоните isSMTP()), вы можете получить подробную расшифровку разговора SMTP, используяSMTPDebug свойство.

Установите эту опцию, включив такую ​​строку в ваш скрипт:

$mail->SMTPDebug = 2;

Вы также получаете преимущество лучшего интерфейса. С mailвы должны настроить все заголовки, приложение и т.д. С библиотекой, есть специальная функция , чтобы сделать это. Это также означает, что функция выполняет все сложные части (например, заголовки).


6
$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
    $subject = $name;
    // To send HTML mail, the Content-type header must be set.
    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= 'From:' . $email. "\r\n"; // Sender's Email
    //$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
    $template = '<div style="padding:50px; color:white;">Hello ,<br/>'
        . '<br/><br/>'
        . 'Name:' .$name.'<br/>'
        . 'Email:' .$email.'<br/>'
        . '<br/>'
        . '</div>';
    $sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
    // Message lines should not exceed 70 characters (PHP rule), so wrap it.
    $sendmessage = wordwrap($sendmessage, 70);
    // Send mail by PHP Mail Function.
    mail($reciver, $subject, $sendmessage, $headers);
    echo "Your Query has been received, We will contact you soon.";
} else {
    echo "<span>* invalid email *</span>";
}

6

Вы можете использовать конфигурационную электронную почту от CodeIgniter . Например, используя SMTP (простой способ):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => 'name@domain.com',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

Меня устраивает!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo не удалось: такой хост не известен. - Если я сталкиваюсь с этой ошибкой, то в чем причина и что нужно сделать?
Чоудхури Саадман Махмид

1
«Работает для меня» - это просто анекдотичная информация, но на самом деле не так уж много объяснений. Пароль порта и smtp будет вводить в заблуждение для большинства пользователей.
Марио

Что такое "электронная почта конфигурации" ? У вас есть ссылка?
Питер Мортенсен

4

Попробуй это

if ($_POST['submit']) {
    $success= mail($to, $subject, $body, $from);
    if($success)
    { 
        echo '
        <p>Your message has been sent!</p>
        ';
    } else { 
        echo '
        <p>Something went wrong, go back and try again!</p>
        '; 
    }
}

4

Возможно проблема в настройке почтового сервера. Чтобы избежать подобных проблем или вам не нужно беспокоиться о проблеме с почтовым сервером, я рекомендую вам использовать PHPMailer .

Это плагин, который имеет все необходимое для отправки почты, и единственное, что вы должны принять во внимание, это включить SMTP-порт (порт: 25 и 465).

require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';

$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
    //Server settings
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'correo@gmail.com';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('correo@gmail.com', 'my name');
    $mail->addAddress('destination@correo.com');

    // Attachments
    $mail->addAttachment('optional file');         // Add files, is optional

    // Content
    $mail->isHTML(true);// Set email format to HTML
    $mail->Subject = utf8_decode("subject");
    $mail->Body    = utf8_decode("mail content");
    $mail->AltBody = '';
    $mail->send();
}
catch (Exception $e) {
    $error = $mail->ErrorInfo;
}

1
В IANA порт 465 заменен на порт 587. Это порт отправки почты по умолчанию. Когда почтовый клиент или исходящий сервер отправляют электронную почту для маршрутизации соответствующим почтовым сервером, он всегда должен использовать порт SMTP 587 в качестве порта по умолчанию. См. Mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Мудрый совет: не открывайте порты на вашем компьютере, если вы не совсем знаете, что делаете!
Вред

3

Убедитесь, что на вашем сервере установлен Sendmail.

Если вы проверили свой код и убедились, что в этом нет ничего плохого, перейдите в / var / mail и проверьте, пуста ли эта папка.

Если он пуст, вам нужно будет сделать:

sudo apt-get install sendmail

если вы находитесь на сервере Ubuntu.


Это слишком грубо, чтобы быть полезным. Простая установка MTA редко позволяет получить к нему доступ. А полное руководство по настройке sendmail / postfix / qmail было бы здесь не по теме.
Марио

Этот комментарий относится к моему ответу? Потому что этого не случилось со мной, и я не решил это точно так же. Существуют различные возможные ответы на этот вопрос, и я был одним из них после того, как попробовал все вышеперечисленное в прошлом, мой ответ решил проблему для меня, поэтому я предложил его здесь в качестве другого потенциального решения.
Даниил

Да, конечно. Это один из многих возможных ответов. Тем не менее, это все еще способ поверхностного ИМО. Обобщение его в «вам нужен MTA», такой как… - и вот несколько связанных с ним руководств по установке… может быть более практичным, однако.
Марио

3

Во-первых, у вас может быть слишком много параметров для функции mail () ... У вас может быть максимум пять, mail(to, subject, message, headers, parameters);

Что касается $fromпеременной, то она должна автоматически исходить от вашего веб-хоста, если вы используете Linux cPanel . Он автоматически приходит от вашего имени пользователя и IP-адреса cPanel.

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

Также убедитесь, что у вас есть правильный порядок переменных в вашей функции mail ().

В mail($to, $subject, $message, etc.)таком порядке, иначе есть шанс, что он не работает.


3

Если у вас возникают проблемы с отправкой писем с помощью PHP, рассмотрите альтернативу, такую ​​как PHPMailer или SwiftMailer .

Я обычно использую SwiftMailer всякий раз, когда мне нужно отправлять письма с PHP.


Основное использование:

require 'mail/swift_required.php';

$message = Swift_Message::newInstance()
    // The subject of your email
    ->setSubject('Jane Doe sends you a message')
    // The from address(es)
    ->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
    // Here, you put the content of your email
    ->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');

if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
    echo json_encode([
        "status" => "OK",
        "message" => 'Your message has been sent!'
    ], JSON_PRETTY_PRINT);
} else {
    echo json_encode([
        "status" => "error",
        "message" => 'Oops! Something went wrong!'
    ], JSON_PRETTY_PRINT);
}

См. Официальную документацию для получения дополнительной информации о том, как использовать SwiftMailer.


3

Для тех, кто не хочет использовать внешние почтовые программы и хочет использовать mail () на выделенном сервере Linux.

О том, как работает PHP-почта, описано php.iniв разделе[mail function] .

Параметр sendmail-pathописывает, как вызывается sendmail. Значением по умолчанию является sendmail -t -i, так что если вы получите работу sendmail -t -i < message.txtв консоли Linux - все будет готово. Вы также можете добавить mail.logв debug и убедиться, что mail () действительно вызывается.

Различные MTA могут реализовать sendmail. Они просто делают символическую ссылку на свои двоичные файлы на это имя. Например, в Debian по умолчанию используется Postfix . Сконфигурируйте свой MTA для отправки почты и протестируйте его с консоли с помощью sendmail -v -t -i < message.txt. Файл message.txtдолжен содержать все заголовки сообщения и тело, адрес получателя для конверта будет взят из To:заголовка. Пример:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

Я предпочитаю использовать ssmtp в качестве MTA, потому что он прост и не требует запуска демона с открытыми портами. ssmtp подходит только для отправки почты с локального хоста . Он также может отправлять проверенные электронные письма через вашу учетную запись в общедоступной почтовой службе. Установите ssmtp и отредактируйте файл конфигурации /etc/ssmtp/ssmtp.conf. Чтобы иметь возможность также получать локальную системную почту на учетные записи Unix (например, оповещения для root от заданий cron), настройте/etc/ssmtp/revaliases файл.

Вот моя конфигурация для моего аккаунта на яндекс почте:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password

2

Это затронет только небольшую группу пользователей, но я бы хотел, чтобы это было задокументировано для этой небольшой группы. Этот член этой маленькой кучки потратил 6 часов на устранение неполадок в рабочем почтовом скрипте PHP из-за этой проблемы.

Если вы собираетесь в университет, в котором работает XAMPP с сайта www.AceITLab.com, вы должны знать, что наш профессор не сказал нам: брандмауэр AceITLab (не брандмауэр Windows) блокирует MercuryMail в XAMPP. Вам придется использовать альтернативный почтовый клиент, груша работает на нас. Вам придется отправить на учетную запись Gmail с низкими настройками безопасности.

Да, я знаю, это совершенно бесполезно для реальной электронной почты. Однако из того, что я видел, академические условия и реальный мир часто имеют мало общего.


Это слишком странно, и больше никому не поможет. Пожалуйста, используйте ссылку [удалить] под своим ответом.
Марио

Что такое «груша» в этом контексте? Вы имеете в виду PEAR , репозиторий программного обеспечения PHP? Или что-то другое? Например, сверстники ?
Питер Мортенсен

Вы действительно имеете в виду «драгоценный маленький» ? Это что-то желать? Почему?
Питер Мортенсен

1

Если вы запускаете этот код на локальном сервере (т.е. на вашем компьютере в целях разработки), он не отправит электронное письмо получателю. Это создаст .txtфайл в папке с именемmailoutput .

В случае, если вы используете бесплатную услугу шланг, как 000webhostили hostinger, эти поставщики услуг отключитьmail() функцию, чтобы предотвратить непреднамеренное использование спуфинга электронной почты, рассылки спама и т. Д. Я предпочитаю связаться с ними, чтобы узнать, поддерживают ли они эту функцию.

Если вы уверены, что поставщик услуг поддерживает функцию mail (), вы можете проверить это руководство по PHP для дальнейшего использования,

PHP mail ()

Чтобы проверить, поддерживает ли ваш хостинг функцию mail (), попробуйте запустить этот код (не забудьте изменить адрес электронной почты получателя) :

<?php
    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" .
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers);
?>

1

Отправить почтуУстановка для Debian 10.0.0 («Buster») была на самом деле тривиальной!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

Стандартная установка пакета sendmail (с разрешением «отправить»):

su -                                        # Install as user 'root'
dpkg --list                                 # Is install necessary?
apt-get install sendmail sendmail-cf m4     # Note multiple package selection
sendmailconfig                              # Respond all 'Y' for new install

Разные полезные команды:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

Подтверждение (возможности отправки)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

Вышеуказанное заняло около 5 минут. Тогда я потратил впустую 5 часов ... Не забудьте проверить папку со спамом !


0

Есть несколько возможностей:

  1. Вы столкнулись с проблемой сервера. На сервере нет почтового сервера. Так что ваша почта не работает, потому что ваш код в порядке, и почта работает с типом.

  2. Вы не получаете объявленную ценность. Попробуйте свой код со статическим значением.

  3. Использовать почту SMTP для отправки почты ...


0

Вы можете использовать libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source

5
Важно упомянуть: это просто mail()оболочка функции. Добавляет только конструкцию сообщения и некоторые уловки.
Марио

0

Вы можете увидеть свои ошибки по:

error_reporting(E_ALL);

И мой пример кода:

<?php
    use PHPMailer\PHPMailer\PHPMailer;
    require 'PHPMailer.php';
    require 'SMTP.php';
    require 'Exception.php';

    $name = $_POST['name'];
    $mailid = $_POST['mail'];
    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->SMTPDebug = 0;                   // Set mailer to use SMTP
    $mail->Host = 'smtp.gmail.com';         // Specify main and backup server
    $mail->Port = 587;                      // Set the SMTP port
    $mail->SMTPAuth = true;                 // Enable SMTP authentication
    $mail->Username = 'someone@gmail.com';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = 'someone@gmail.com';
    $mail->FromName = 'name';
    $mail->AddAddress($mailid, $name);       // Name is optional
    $mail->IsHTML(true);                     // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'Here is your message' ;
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
    if (!$mail->Send()) {
       echo 'Message could not be sent.';
       echo 'Mailer Error: ' . $mail->ErrorInfo;
       exit;
    }
    echo 'Message has been sent';
?>

1
SMTPDebug = 0не полезно Обычный «пароль» также не будет работать с GMail. Этот ответ не очень помогает здесь.
Марио

-2

Если ваша система sendmail работает, ваш код должен быть изменен следующим образом:

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

Это позволяет отправлять электронные письма в формате HTML.

Из заметного интереса:

  1. мы создали строку из нескольких строк заголовка (каждая строка разделена \ r \ n);
  2. мы добавили Content-type, чтобы выразить, что мы возвращаем HTML, чтобы вы могли создавать более качественные электронные письма (вы можете добавить любой HTML-код, который вы хотите, включая CSS, к вашему сообщению, как если бы вы делали это на HTML-странице).

Примечание: <<<EOBсинтаксис требует, чтобы последний маркер EOB начинался как начало строки и не имел пробела или другого символа после точки с запятой.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.