Funkcja poczty PHP nie kończy wysyłania wiadomości e-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>';
        }
    }
?>

Próbowałem utworzyć prosty formularz poczty. Sam formularz znajduje się na mojej index.htmlstronie, ale przechodzi na osobną stronę „dziękuję za przesłanie” thankyou.php, na której znajduje się powyższy kod PHP. Kod przesyła się idealnie, ale nigdy nie wysyła wiadomości e-mail. Jak mogę to naprawić?


2
to twój program na lokalnym komputerze lub na żywo
Tamil Selvan C

6
1. czy jesteś pewien, że nie wchodzi w twój spam? 2. Czy masz skonfigurowane sendmail na swoim urządzeniu?
Steven Moseley,

jest na żywym hoście, nie wchodzi do mojego spamu .. nie jestem pewien, co masz na myśli, mówiąc, że skonfigurowałem sendmaila na moim urządzeniu, więc zakładam, że nie?
user3818620,

spróbuj wysłać bez$from
Artem Ilchenko

Odpowiedzi:


512

Chociaż istnieją części tej odpowiedzi, które dotyczą tylko korzystania z mail()samej funkcji, wiele z tych kroków rozwiązywania problemów można zastosować do dowolnego systemu pocztowego PHP.

Istnieje wiele powodów, dla których skrypt nie wysyła wiadomości e-mail. Trudno jest zdiagnozować te rzeczy, chyba że wystąpi oczywisty błąd składniowy. Bez tego musisz przejrzeć poniższą listę kontrolną, aby znaleźć potencjalne pułapki, które możesz napotkać.

Upewnij się, że raportowanie błędów jest włączone i ustawione na zgłaszanie wszystkich błędów

Zgłaszanie błędów jest niezbędne do usuwania błędów w kodzie i ogólnych błędów napotykanych przez PHP. Aby otrzymywać te błędy, należy włączyć raportowanie błędów. Umieszczenie następującego kodu na górze plików PHP (lub w głównym pliku konfiguracyjnym) umożliwi raportowanie błędów.

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

Zobacz Jak mogę uzyskać przydatne komunikaty o błędach w PHP? - ta odpowiedź zawiera więcej szczegółów na ten temat.

Upewnij się, że mail()funkcja została wywołana

Może się to wydawać głupie, ale częstym błędem jest zapomnienie o umieszczeniu mail()funkcji w kodzie. Upewnij się, że tam jest i nie jest komentowany.

Upewnij się, że mail()funkcja została poprawnie wywołana

bool mail (ciąg $ do, ciąg $ temat, ciąg $ wiadomość [, ciąg $ dodatkowe_podstawy [, ciąg $ dodatkowe_parametry]])

Funkcja poczty przyjmuje trzy wymagane parametry i opcjonalnie czwarty i piąty. Jeśli Twoje wezwanie do mail()nie ma co najmniej trzech parametrów, zakończy się niepowodzeniem.

Jeśli Twoje wezwanie do mail()nie ma poprawnych parametrów we właściwej kolejności, również się nie powiedzie.

Sprawdź dzienniki poczty serwera

Twój serwer internetowy powinien rejestrować wszystkie próby wysłania za jego pośrednictwem wiadomości e-mail. Lokalizacja tych dzienników będzie się różnić (być może będziesz musiał zapytać administratora serwera, gdzie się znajdują), ale zwykle można je znaleźć w katalogu głównym użytkownika pod logs. Wewnątrz znajdują się komunikaty o błędach, które serwer zgłosił, jeśli takie istnieją, związane z próbami wysłania wiadomości e-mail.

Sprawdź awarię połączenia z portem

Blok portów jest bardzo częstym problemem, z którym zmaga się większość programistów, integrując swój kod w celu dostarczania wiadomości e-mail za pomocą SMTP. I można to łatwo prześledzić na serwerach maillogs (lokalizacja serwera dziennika poczty może się różnić w zależności od serwera, jak wyjaśniono powyżej). W przypadku korzystania z udostępnionego serwera hostingowego porty 25 i 587 pozostają domyślnie zablokowane. Ten blok został celowo wykonany przez Twojego dostawcę hostingu. Dotyczy to nawet niektórych serwerów dedykowanych. Gdy te porty są zablokowane, spróbuj połączyć się przy użyciu portu 2525. Jeśli okaże się, że ten port jest również zablokowany, jedynym rozwiązaniem jest skontaktowanie się z dostawcą usług hostingowych w celu odblokowania tych portów.

Większość dostawców hostingu blokuje te porty e-mail, aby chronić swoją sieć przed wysyłaniem spamu.

Użyj portów 25 lub 587 dla połączeń zwykłych / TLS i portu 465 dla połączeń SSL. W przypadku większości użytkowników zaleca się użycie portu 587, aby uniknąć limitów prędkości ustalanych przez niektórych dostawców hostingu.

Nie używaj operatora eliminacji błędów

Kiedy operator tłumienia błędów @ jest dołączony do wyrażenia w PHP, wszelkie komunikaty o błędach, które mogą być generowane przez to wyrażenie, zostaną zignorowane. Istnieją okoliczności, w których użycie tego operatora jest konieczne, ale wysyłanie poczty nie jest jednym z nich.

Jeśli Twój kod zawiera @mail(...), być może ukrywasz ważne komunikaty o błędach, które pomogą Ci to debugować. Usuń @i sprawdź, czy zgłoszono jakiekolwiek błędy.

To tylko wskazane, kiedy sprawdzić werror_get_last() prawo potem do konkretnych awarii.

Sprawdź mail()wartość zwracaną

mail()Funkcja:

Zwraca, TRUEjeśli poczta została pomyślnie przyjęta do dostarczenia, w FALSEprzeciwnym razie. Ważne jest, aby pamiętać, że fakt, iż poczta została zaakceptowana do dostarczenia, NIE oznacza, że ​​faktycznie dotrze do miejsca docelowego.

Należy o tym pamiętać, ponieważ:

  • Jeśli otrzymasz FALSEwartość zwrotną, wiesz, że błąd polega na tym, że serwer akceptuje pocztę. Prawdopodobnie nie jest to problem z kodowaniem, ale problem z konfiguracją serwera. Musisz porozmawiać z administratorem systemu, aby dowiedzieć się, dlaczego tak się dzieje.
  • Jeśli otrzymasz TRUEwartość zwrotną, nie oznacza to, że Twój e-mail na pewno zostanie wysłany. Oznacza to po prostu, że e-mail został pomyślnie wysłany do odpowiedniego modułu obsługi na serwerze przez PHP. Jest jeszcze więcej punktów awarii, na które nie ma wpływu PHP, które mogą spowodować, że wiadomość e-mail nie zostanie wysłana.

Więc FALSEpomogą skierować Cię w dobrym kierunku, natomiast TRUEma nie musi oznaczać, e-mail został wysłany pomyślnie. Należy to zauważyć!

Upewnij się, że twój dostawca hostingu pozwala ci wysyłać e-maile i nie ogranicza wysyłania e-maili

Wielu współdzielonych webhostów, zwłaszcza darmowych dostawców hostingu, albo nie zezwala na wysyłanie e-maili z ich serwerów, albo ogranicza ilość, którą można wysłać w danym okresie. Wynika to z ich starań, aby spamerzy nie mogli korzystać z tańszych usług.

Jeśli uważasz, że Twój host ma ograniczenia dotyczące wysyłania wiadomości e-mail lub blokuje wysyłanie wiadomości e-mail, zapoznaj się z często zadawanymi pytaniami, aby sprawdzić, czy zawierają takie ograniczenia. W przeciwnym razie może być konieczne skontaktowanie się z obsługą klienta w celu sprawdzenia, czy istnieją jakieś ograniczenia dotyczące wysyłania wiadomości e-mail.

Sprawdź foldery spamu; zapobiegać oznaczaniu wiadomości e-mail jako spam

Często z różnych powodów wiadomości e-mail wysyłane przez PHP (i inne języki programowania po stronie serwera) trafiają do folderu spamu odbiorcy. Zawsze sprawdzaj tam przed rozwiązaniem problemu z kodem.

Aby uniknąć wysyłania poczty wysyłanej przez PHP do folderu spamu odbiorcy, możesz wykonywać różne czynności, zarówno w kodzie PHP, jak i w inny sposób, aby zminimalizować szanse, że wiadomości e-mail zostaną oznaczone jako spam. Dobre wskazówki Michiela de Mare obejmują:

  • Użyj metod uwierzytelniania poczty e-mail, takich jak SPF i DKIM, aby udowodnić, że wiadomości e-mail i nazwa domeny należą do siebie, i aby zapobiec fałszowaniu nazwy domeny. Witryna SPF zawiera kreatora do generowania informacji DNS dla Twojej witryny.
  • Sprawdzić swoje odwrotnego DNS , aby upewnić się, że adres IP serwera pocztowego punktów do nazwy domeny, który służy do wysyłania poczty.
  • Upewnij się, że używany adres IP nie znajduje się na czarnej liście
  • Upewnij się, że adres zwrotny jest prawidłowym, istniejącym adresem.
  • W polu Do wpisz pełną, prawdziwą nazwę adresata, a nie tylko adres e-mail (np "John Smith" <john@blacksmiths-international.com>.).
  • Monitoruj swoje konta nadużyć, takie jak nadużycie@twojadomena.com i postmaster@twojadomena.com. Oznacza to - upewnij się, że te konta istnieją, przeczytaj, co jest do nich wysyłane, i reaguj na skargi.
  • Na koniec spraw, aby naprawdę łatwo było zrezygnować z subskrypcji. W przeciwnym razie użytkownicy anulują subskrypcję, naciskając przycisk spamu , co wpłynie na twoją reputację.

Zobacz Jak się upewnić, że wiadomości e-mail wysyłane programowo nie są automatycznie oznaczane jako spam? więcej na ten temat.

Upewnij się, że wszystkie nagłówki wiadomości są dostarczone

Niektóre programy spamujące odrzucają pocztę, jeśli brakuje w niej wspólnych nagłówków, takich jak „Od” i „Odpowiedź”:

$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);

Upewnij się, że nagłówki wiadomości nie zawierają błędów składniowych

Nieprawidłowe nagłówki są tak samo złe, jak brak nagłówków. Wystarczy jeden niepoprawny znak, aby wykoleić Twój e-mail. Sprawdź dokładnie, czy Twoja składnia jest poprawna, ponieważ PHP nie wykryje tych błędów.

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Nie używaj fałszywego From:nadawcy

Chociaż poczta musi mieć nadawcę From:, nie możesz po prostu użyć żadnej wartości. W szczególności adresy wysyłane przez użytkowników są pewnym sposobem na zablokowanie wiadomości e-mail:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

Powód: twój serwer internetowy lub wysyłający nie jest na białej liście SPF / DKIM, aby udawać, że jest odpowiedzialny za adresy @hotmail lub @gmail. Może nawet po cichu upuszczać wiadomości e-mail z From:domenami nadawców, dla których nie jest skonfigurowany.

Upewnij się, że wartość odbiorcy jest poprawna

Czasami problem jest tak prosty, jak niepoprawna wartość dla odbiorcy wiadomości e-mail. Może to być spowodowane użyciem niepoprawnej zmiennej.

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Innym sposobem na sprawdzenie tego jest utrwalenie wartości odbiorcy w mail()wywołaniu funkcji:

mail('user@example.com', $subject, $message, $headers); 

Może to dotyczyć wszystkich mail()parametrów.

Wyślij na wiele kont

Aby wykluczyć problemy z kontem e-mail, wyślij wiadomość e-mail na wiele kont e-mail u różnych dostawców poczty e-mail . Jeśli wiadomości e-mail nie docierają do konta Gmail użytkownika, wyślij te same wiadomości e-mail na konto Yahoo, Hotmail i zwykłe konto POP3 (takie jak konto e-mail dostarczone przez dostawcę usług internetowych).

Jeśli wiadomości e-mail dotrą do wszystkich lub niektórych innych kont e-mail, wiesz, że Twój kod wysyła wiadomości e-mail, ale prawdopodobnie dostawca kont e-mail blokuje je z jakiegoś powodu. Jeśli wiadomość e-mail nie dotrze do żadnego konta e-mail, problem najprawdopodobniej będzie związany z Twoim kodem.

Upewnij się, że kod odpowiada metodzie formularza

Jeśli ustawiłeś metodę formularza na POST, upewnij się, że używasz $_POSTdo szukania wartości formularza. Jeśli ustawiłeś GETlub w ogóle go nie ustawiłeś, upewnij się, że używasz $_GETdo szukania wartości formularza.

Upewnij się, że actionwartość formularza wskazuje prawidłową lokalizację

Upewnij się, że actionatrybut formularza zawiera wartość wskazującą na kod pocztowy PHP.

<form action="send_email.php" method="POST">

Upewnij się, że host obsługuje wysyłanie wiadomości e-mail

Niektórzy dostawcy usług hostingowych nie zezwalają ani nie umożliwiają wysyłania wiadomości e-mail za pośrednictwem swoich serwerów. Przyczyny tego mogą być różne, ale jeśli wyłączyli wysyłanie poczty, będziesz musiał użyć alternatywnej metody, która korzysta z usług strony trzeciej, aby wysłać te wiadomości e-mail za Ciebie.

Wiadomość e-mail do pomocy technicznej (po podróży do pomocy technicznej online lub FAQ) powinna wyjaśnić, czy funkcje poczty e-mail są dostępne na twoim serwerze.

Upewnij się, że localhostserwer pocztowy jest skonfigurowany

Jeśli programujesz na lokalnej stacji roboczej za pomocą WAMP, MAMP lub XAMPP, serwer e-mail prawdopodobnie nie jest zainstalowany na twojej stacji roboczej. Bez niego PHP nie może domyślnie wysyłać poczty.

Możesz temu zaradzić, instalując podstawowy serwer pocztowy. W systemie Windows możesz skorzystać z bezpłatnej poczty Mercury .

Możesz również użyć SMTP do wysyłania wiadomości e-mail. Zobacz tę wielką odpowiedź od Vikas Dwivedi aby dowiedzieć się jak to zrobić.

Włącz niestandardowe PHP mail.log

Oprócz pliku dziennika MTA i PHP możesz włączyć rejestrowanie dla tej mail()funkcji . Nie rejestruje pełnej interakcji SMTP, ale przynajmniej parametry wywołania funkcji i skrypt wywołania.

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

Szczegółowe informacje można znaleźć na stronie http://php.net/manual/en/mail.configuration.php . (Najlepiej włączyć te opcje w php.inilub .user.inilub .htaccess.)

Sprawdź za pomocą usługi testowania poczty

Istnieją różne usługi sprawdzania dostawy i spamowania, których możesz użyć do przetestowania konfiguracji MTA / serwera WWW. Zazwyczaj wysyłasz sondę pocztową na adres:, a następnie otrzymujesz raport doręczenia i więcej konkretnych awarii lub analiz później:

Użyj innego programu pocztowego

Wbudowana mail()funkcja PHP jest przydatna i często wykonuje zadanie, ale ma swoje wady . Na szczęście istnieją alternatywy, które oferują większą moc i elastyczność, w tym radzenie sobie z wieloma problemami opisanymi powyżej:

Wszystko to można połączyć z profesjonalnym serwerem / dostawcą usług SMTP. (Ponieważ typowe wspólne plany hostingowe 08/15 są trafione lub pominięte, jeśli chodzi o konfigurację / konfigurację poczty e-mail)


11
Dobrze napisane, John. Chciałbym tylko dodać jeszcze jedną rzecz: sprawdzenie dzienników serwera pocztowego wysyłającego serwera pocztowego (niezależnie od tego, czy jest on hostowany lokalnie, czy zdalnie), jeśli to możliwe, często może rzucić światło na to, co powoduje problem. Te dzienniki powinny pokazywać 1) czy wiadomość została otrzymana ze skryptu PHP przez wysyłający serwer pocztowy, a jeśli tak, 2) czy odbierająca MX zaakceptowała dostarczenie z wysyłającego serwera pocztowego.
mti2935

@ mti2935 To bardzo pomocne Jestem zaskoczony, że tego nie zauważyłem. Wkrótce to dodam. :)
John Conde

1
chciałbym zacząć od dont use mail(), robi tak kiepską robotę i jest trudniejszy do debugowania niż jakakolwiek inna biblioteka poczty

1
ta sama strona na 000webhost wysyła wiadomości e-mail z powodzeniem i szybko w domenie netai.net, ale na site88.net mam tę samą stronę, którą otrzymuję w konsoli, którą wiadomość wysyła pomyślnie, ale nie otrzymuję żadnych wiadomości. Również w domenie comuf.com pojawia się błąd (ta sama strona na tym samym hoście działa tylko w domenie netai.net, net16.net też działa)
Nicolas Papaconstantinou

1
moje pytanie ( stackoverflow.com/questions/44866673/... ) zostało oznaczone jako duplikat tego pytania , ale nadal nie mogę tego rozgryźć. Jakieś sugestie?
Zachary Elkins,

37

Dodaj nagłówek wiadomości w funkcji poczty:

$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. Zawsze próbuj wysyłać nagłówki w funkcji poczty.
  2. Jeśli wysyłasz pocztę za pośrednictwem hosta lokalnego, wykonaj ustawienia SMTP dotyczące wysyłania poczty.
  3. Jeśli wysyłasz pocztę przez serwer, sprawdź, czy funkcja wysyłania wiadomości e-mail jest włączona na serwerze.

20

Jeśli używasz konfiguracji SMTP do wysyłania wiadomości e-mail, spróbuj zamiast tego użyć PHPMailer . Możesz pobrać bibliotekę ze strony https://github.com/PHPMailer/PHPMailer .

Mój e-mail utworzyłem w ten sposób:

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
Musiałem także użyć: wymagania („phpmailer / class.smtp.php”);
Doug

15

Po prostu dodaj nagłówki przed wysłaniem wiadomości:

<?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);

I jeszcze jedno. mail()Funkcja nie działa w localhost. Prześlij swój kod na serwer i spróbuj.


1
to faktycznie spowodowało przesłanie formularza - moje pytanie brzmiałoby teraz: jak pokazać użytkownikowi wpisany adres e-mail, teraz, gdy zastąpiłem go nagłówkiem ...
user3818620

zapobiegnie przesyłaniu wiadomości z folderu ze spamem. Widziałem, czy wysyłamy pocztę większą niż 10 za pomocą tej metody, której użyłeś w kodzie Gmail wysyła tę pocztę do spamu.
jewelhuq

OP ma następujący wiersz: $from = 'From: yoursite.com'; który nie wygląda na pełny poprawny adres e-mail, nie ma części lokalnej. Zastąpiłeś nagłówek From i dodałeś dodatkowe. A raczej $frompowyższe jest niepotrzebne w twoim przykładzie. A zniekształcenie było prawdopodobnie pierwotnym problemem PO.
Progrock,

13

Działa dla mnie na 000webhost, wykonując następujące czynności:

$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";

Wpisz bezpośrednio adres e-mail podczas wysyłania wiadomości e-mail:

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

Użyj ''i nie "".

Ten kod działa, ale wiadomość e-mail została odebrana z półgodzinnym opóźnieniem.


10

Przeważnie mail()funkcja jest wyłączona w hostingu współdzielonym. Lepszą opcją jest użycie SMTP. Najlepszą opcją byłby Gmail lub 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();
}
?>

Czy warto zapisać użytkownika i hasło smtp w postaci zwykłego tekstu na serwerze?
Juri

@Juri prawdopodobnie nie ... Boże, nie mogę wymyślić, jak uruchomić funkcję poczty

9

Jeśli używasz tylko tej mail()funkcji, musisz wypełnić plik konfiguracyjny.

Musisz otworzyć rozszerzenie poczty, ustawić SMTP smtp_portitd. I, co najważniejsze, swoją nazwę użytkownika i hasło. Bez tego poczta nie może zostać wysłana. Możesz także użyć tej PHPMailklasy do wysłania.


9

Wypróbuj te dwie rzeczy osobno i razem:

  1. usunąć if($_POST['submit']){}
  2. usuń $from(tylko moje jelita)

8

Myślę, że to powinno wystarczyć. Właśnie dodałem if(isseti dodałem konkatenację do zmiennych w ciele, aby oddzielić PHP od 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

Dla każdego, kto uzna to za postęp, nie polecam używania mail. Jest kilka odpowiedzi na to pytanie, ale nie dlaczego .

mailFunkcja PHP jest nie tylko nieprzezroczysta, ale w pełni opiera się na MTA, którego używasz (tj. Sendmail ) do wykonywania pracy. mailbędzie tylko powiedzieć, jeśli MTA nie udało się go przyjąć (tj Sendmail spadł podczas próby wysłania). Nie może powiedzieć, czy poczta się powiodła, ponieważ została przekazana. Jako takie (jak szczegóły odpowiedzi Johna Conde'a ), możesz teraz bawić się dziennikami MTA i mieć nadzieję, że powie ci wystarczająco dużo o tym, że nie udało się go naprawić. Jeśli korzystasz z hosta współdzielonego lub nie masz dostępu do dzienników MTA, nie masz szczęścia. Niestety, domyślne ustawienia dla większości instalacji waniliowych dla Linuksa obsługują to w ten sposób.

Biblioteka poczty ( PHPMailer , Zend Framework 2+ itp.) Robi coś zupełnie innego mail. Otwierają gniazdo bezpośrednio do odbierającego serwera poczty, a następnie wysyłają polecenia poczty SMTP bezpośrednio przez to gniazdo. Innymi słowy, klasa działa jak własny MTA (zwróć uwagę, że możesz mailpolecić bibliotekom, by ostatecznie wysłały pocztę, ale zdecydowanie zalecam, abyś tego nie robił).

Oznacza to, że możesz bezpośrednio zobaczyć odpowiedzi z serwera odbierającego (na przykład w PHPMailer możesz włączyć wyjście debugowania ). Nigdy więcej zgadywania, czy wiadomość nie została wysłana i dlaczego.

Jeśli używasz SMTP (tj. Dzwonisz isSMTP()), możesz uzyskać szczegółowy zapis rozmowy SMTP za pomocą tej SMTPDebugwłaściwości.

Ustaw tę opcję, włączając w skrypcie taką linię:

$mail->SMTPDebug = 2;

Otrzymasz również korzyść z lepszego interfejsu. Ponieważ mailmusisz skonfigurować wszystkie nagłówki, załączniki itp. Dzięki bibliotece masz do tego dedykowaną funkcję. Oznacza to również, że funkcja wykonuje wszystkie trudne części (takie jak nagłówki).


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

Możesz użyć e-maila konfiguracyjnego CodeIgniter . Na przykład za pomocą SMTP (prosty sposób):

$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
}

Mi to pasuje!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo nie powiodło się: Żaden taki host nie jest znany. - Jeśli napotkałem ten błąd, jaki jest powód i co należy zrobić?
Choudhury Saadmaan Mahmid

1
„Działa dla mnie” to tylko niepotwierdzone informacje, ale tak naprawdę niewiele z wyjaśnień. Hasło portu i smtp byłoby mylące dla większości użytkowników.
mario

Co to jest „email konfiguracyjny” ? Czy masz referencje?
Peter Mortensen,

4

Spróbuj tego

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

Być może problemem jest konfiguracja serwera pocztowego. Aby uniknąć tego typu problemów lub nie musisz się martwić o problem z serwerem pocztowym, zalecamy korzystanie z PHPMailer .

Jest to wtyczka, która ma wszystko, co niezbędne do wysyłania poczty, a jedyną rzeczą, którą musisz wziąć pod uwagę, jest włączenie portu SMTP (Port: 25 i 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 zastąpiła port 465 portem 587. Jest to domyślny port do przesyłania poczty. Gdy klient poczty e-mail lub serwer poczty wychodzącej przesyła wiadomość e-mail do routingu przez odpowiedni serwer poczty, powinien zawsze używać portu SMTP 587 jako portu domyślnego. Zobacz mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Mądra rada: nie otwieraj portów w komputerze, jeśli nie jesteś całkowicie świadomy tego, co robisz!
Harm

3

Upewnij się, że masz zainstalowany Sendmail na swoim serwerze.

Jeśli sprawdziłeś kod i sprawdziłeś, że nie ma w tym nic złego, przejdź do / var / mail i sprawdź, czy ten folder jest pusty.

Jeśli jest pusty, musisz wykonać:

sudo apt-get install sendmail

jeśli jesteś na serwerze Ubuntu.


To zbyt gruba, by było przydatne. Samo zainstalowanie MTA rzadko pozwoli na to. Pełny przewodnik instalacji sendmail / postfix / qmail byłby tutaj nie na temat.
mario

Czy ten komentarz odnosi się do mojej odpowiedzi? Ponieważ mi się to nie zdarzyło i nie rozwiązałem tego w ten sam dokładny sposób. Istnieją różne możliwe odpowiedzi na to pytanie, moje jest jednym z nich po wypróbowaniu wszystkich powyższych w przeszłości, moja odpowiedź rozwiązała dla mnie problem, więc zaproponowałem to tutaj jako inne potencjalne rozwiązanie.
Daniel

Tak, oczywiście. To jedna z wielu możliwych odpowiedzi. Jednak nadal jest to droga do powierzchownego IMO. Uogólnienie go na „potrzebujesz MTA”, takie jak… - a tutaj jest kilka powiązanych przewodników konfiguracji… może być jednak bardziej praktyczne.
mario

3

Przede wszystkim możesz mieć zbyt wiele parametrów dla funkcji mail () ... Możesz mieć maksymalnie pięć, mail(to, subject, message, headers, parameters);

Jeśli chodzi o $fromzmienną, powinna ona automatycznie pochodzić z twojego hosta, jeśli używasz Linuksa cPanel . Automatycznie pochodzi od nazwy użytkownika i adresu 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";

Upewnij się także, że masz prawidłową kolejność zmiennych w funkcji mail ().

W mail($to, $subject, $message, etc.)tej kolejności, w przeciwnym razie istnieje szansa, że ​​nie zadziała.


3

Jeśli masz problemy z wysyłaniem maili z PHP, należy rozważyć alternatywę jak PHPMailer lub SwiftMailer .

Zwykle używam SwiftMailer za każdym razem, gdy potrzebuję wysyłać maile za pomocą PHP.


Podstawowe użycie:

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);
}

Zobacz oficjalną dokumentację, aby uzyskać więcej informacji na temat korzystania z SwiftMailer.


3

Dla tych, którzy nie chcą korzystać z zewnętrznych programów pocztowych i chcą wysyłać pocztę () na dedykowanym serwerze Linux.

Sposób, w jaki maile PHP, opisano php.iniw rozdziale[mail function] .

Parametr sendmail-pathopisuje, jak wywoływany jest sendmail. Wartością domyślną jest sendmail -t -i, więc jeśli dostaniesz działającą sendmail -t -i < message.txtkonsolę Linux - to koniec. Możesz także dodać mail.logdo debugowania i upewnić się, że mail () jest naprawdę wywoływany.

Można wdrożyć różne MTA sendmail. Po prostu tworzą symboliczne łącze do swoich plików binarnych pod tą nazwą. Na przykład w Debianie domyślnym jest Postfix . Skonfiguruj MTA do wysyłania poczty i przetestuj go z konsoli za pomocą sendmail -v -t -i < message.txt. Plik message.txtpowinien zawierać wszystkie nagłówki wiadomości oraz treść, adres docelowy koperty zostanie pobrany z To:nagłówka. Przykład:

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

Text body.

Wolę używać ssmtp jako MTA, ponieważ jest prosty i nie wymaga uruchamiania demona z otwartymi portami. ssmtp pasuje tylko do wysyłania poczty z hosta lokalnego . Może również wysyłać uwierzytelnione wiadomości e-mail za pośrednictwem konta w publicznej usłudze pocztowej. Zainstaluj ssmtp i edytuj plik konfiguracyjny /etc/ssmtp/ssmtp.conf. Aby móc również odbierać pocztę systemu lokalnego na konta Unix (na przykład alerty o rootowaniu z zadań crona), skonfiguruj/etc/ssmtp/revaliases plik.

Oto moja konfiguracja mojego konta na poczcie Yandex:

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

2

Wpłynie to tylko na niewielką garstkę użytkowników, ale chciałbym, aby zostało to udokumentowane dla tej małej garstki. Ten niewielki garstka spędził 6 godzin na rozwiązywaniu problemów z działającym skryptem pocztowym PHP z powodu tego problemu.

Jeśli wybierasz się na uniwersytet prowadzący XAMPP z www.AceITLab.com, powinieneś wiedzieć, czego nasz profesor nam nie powiedział: Zapora AceITLab (nie zapora systemu Windows) blokuje MercuryMail w XAMPP. Będziesz musiał użyć alternatywnego klienta pocztowego, gruszka dla nas pracuje. Musisz wysłać na konto Gmail z niskim poziomem zabezpieczeń.

Tak, wiem, jest to całkowicie bezużyteczne w przypadku wiadomości e-mail z prawdziwego świata. Jednak z tego, co widziałem, środowiska akademickie i rzeczywisty świat często mają ze sobą niewiele wspólnego.


Jest to zbyt dziwnie specyficzne i naprawdę nie pomoże nikomu innemu. Proszę użyć linku [usuń] poniżej odpowiedzi.
mario

Co to jest „gruszka” w tym kontekście? Masz na myśli PEAR , repozytorium oprogramowania PHP? Albo coś innego? Np. Rówieśnik ?
Peter Mortensen,

Czy naprawdę masz na myśli „cenny mały” ? Czy to coś, o czym marzysz? Dlaczego?
Peter Mortensen,

1

Jeśli uruchamiasz ten kod na serwerze lokalnym (tj. Na komputerze w celach programistycznych), wiadomość e-mail nie zostanie wysłana do odbiorcy. Utworzy .txtplik w folderze o nazwiemailoutput .

W przypadku korzystania z bezpłatnej usługi węży, takiej jak 000webhostlub hostinger, dostawcy usług wyłączająmail() funkcję, aby zapobiec niezamierzonemu wykorzystywaniu fałszowania wiadomości e-mail, spamowania itp. Wolę, abyś skontaktował się z nimi, aby sprawdzić, czy obsługują tę funkcję.

Jeśli masz pewność, że usługodawca obsługuje funkcję mail (), możesz sprawdzić ten podręcznik PHP w celu uzyskania dalszych informacji,

Poczta PHP ()

Aby sprawdzić, czy Twoja usługa hostingowa obsługuje funkcję mail (), spróbuj uruchomić ten kod (pamiętaj, aby zmienić adres e-mail odbiorcy) :

<?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

Instalacja Sendmaila dla Debiana 10.0.0 („Buster”) była w rzeczywistości trywialna!

php.ini

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

Standardowa instalacja pakietu sendmaila (zezwalająca na „wysyłanie”):

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

Różne przydatne polecenia:

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

Weryfikacja (możliwości wysyłania)

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

Powyższe zajęło około 5 minut. Potem zmarnowałem 5 godzin ... Nie zapomnij sprawdzić folderu ze spamem !


0

Istnieje kilka możliwości:

  1. Masz problem z serwerem. Serwer nie ma żadnego serwera poczty. Twoja poczta nie działa, ponieważ kod działa poprawnie, a poczta działa z typem.

  2. Nie otrzymujesz zaksięgowanej wartości. Wypróbuj swój kod o wartości statycznej.

  3. Wysyłaj pocztę za pomocą wiadomości SMTP ...


0

Możesz użyć 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
Ważne, aby wspomnieć: jest to tylko mail()opakowanie funkcji. Dodaje tylko konstrukcję wiadomości i kilka sztuczek.
mario

0

Możesz zobaczyć swoje błędy poprzez:

error_reporting(E_ALL);

A mój przykładowy kod to:

<?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 = 0nie jest pomocny. Zwykłe „hasło” nie będzie działać z Gmailem. Ta odpowiedź niewiele tu wnosi.
mario

-2

Pod warunkiem, że twój system sendmail działa, twój kod musi zostać zmodyfikowany w następujący sposób:

<?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>'; 
        }
    }
?>

Umożliwia to wysyłanie wiadomości e-mail opartych na języku HTML.

Godne uwagi:

  1. zbudowaliśmy ciąg multilinii nagłówka (każda linia jest oddzielona \ r \ n);
  2. dodaliśmy Typ treści, aby wyrazić, że zwracamy HTML, abyś mógł tworzyć lepsze wiadomości e-mail (możesz dodać dowolny kod HTML, w tym CSS, do swojej wiadomości, tak jak na stronie HTML).

Uwaga: <<<EOBskładnia wymaga, aby ostatni znacznik EOB zaczynał się od początku linii i nie ma spacji ani żadnego innego znaku po średniku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.