Funkcja poczty PHP nie kończy wysyłania wiadomości e-mail
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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 stworzyć prosty formularz pocztowy. Sam formularz jest na mojej index.html
stronie, ale jest on przesyłany na osobną stronę z podziękowaniem za przesłanie thankyou.php
, gdzie osadzony jest powyższy kod PHP. Kod jest przesyłany idealnie, ale nigdy nie wysyła wiadomości e-mail. Jak mogę to naprawić?
Odpowiedzi
Chociaż istnieją fragmenty tej odpowiedzi, które odnoszą się tylko do użycia mail()
samej funkcji, wiele z tych kroków rozwiązywania problemów można zastosować w każdym systemie pocztowym PHP.
Istnieje wiele powodów, dla których Twój skrypt wydaje się nie wysyłać e-maili. Trudno jest zdiagnozować te rzeczy, chyba że występuje oczywisty błąd składniowy. Bez niego 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 skonfiguruj raportowanie wszystkich błędów
Zgłaszanie błędów jest niezbędne do wykorzenienia 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 poniższego kodu u góry 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ź po 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 wykomentowany.
Upewnij się, że mail()
funkcja jest wywoływana poprawnie
bool mail (string $to , string $temat, ciąg $message [, string $dodatkowe_nagłówki [, string $ dodatkowe_parametry]])
Funkcja poczty przyjmuje trzy wymagane parametry oraz opcjonalnie czwarty i piąty. Jeśli twoje wywołanie mail()
nie ma co najmniej trzech parametrów, zakończy się niepowodzeniem.
Jeśli wywołanie funkcji mail()
nie ma poprawnych parametrów we właściwej kolejności, również zakończy się niepowodzeniem.
Sprawdź dzienniki poczty serwera
Twój serwer WWW powinien rejestrować wszystkie próby wysłania wiadomości e-mail za jego pośrednictwem. Lokalizacja tych dzienników będzie się różnić (może być konieczne spytanie administratora serwera, gdzie się znajdują), ale zwykle można je znaleźć w katalogu głównym użytkownika pod logs
. Wewnątrz będą znajdować się komunikaty o błędach, które zgłosił serwer, związane z twoimi próbami wysłania wiadomości e-mail.
Sprawdź błąd połączenia portu
Blokowanie portów to bardzo częsty problem, z którym boryka się większość programistów podczas integracji swojego kodu w celu dostarczania wiadomości e-mail przy użyciu protokołu SMTP. Można to łatwo prześledzić w dziennikach zdarzeń serwera (lokalizacja dziennika serwera poczty może się różnić w zależności od serwera, jak wyjaśniono powyżej). W przypadku korzystania ze współdzielonego serwera hostingowego porty 25 i 587 pozostają domyślnie zablokowane. Ta blokada została celowo wykonana przez dostawcę usług hostingowych. Dzieje się tak nawet w przypadku niektórych serwerów dedykowanych. Gdy te porty są zablokowane, spróbuj połączyć się za pomocą 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 usług hostingowych 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ąć ograniczeń szybkości ustalanych przez niektórych dostawców usług hostingowych.
Nie używaj operatora eliminacji błędów
Gdy operator pomijania błędów @
jest dołączany do wyrażenia w PHP, wszelkie komunikaty o błędach, które mogą być generowane przez to wyrażenie, będą ignorowane. 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 zobacz, czy są zgłaszane jakieś błędy.
Jest to wskazane tylko wtedy, gdy zaraz potem skonsultujesz się zerror_get_last()
konkretnymi awariami.
Sprawdź mail()
zwracaną wartość
mail()
Funkcja:
Zwroty,
TRUE
jeśli przesyłka została pomyślnie przyjęta do dostarczenia, wFALSE
przeciwnym razie. Należy pamiętać, że fakt, że przesyłka została przyjęta do doręczenia, NIE oznacza, że dotrze ona do zamierzonego miejsca przeznaczenia.
Należy o tym pamiętać, ponieważ:
- Jeśli otrzymasz
FALSE
wartość zwracaną, wiesz, że błąd leży po stronie serwera, który akceptuje twoją pocztę. Prawdopodobnie nie jest to problem z kodowaniem, ale z konfiguracją serwera. Musisz porozmawiać z administratorem systemu, aby dowiedzieć się, dlaczego tak się dzieje. - Jeśli otrzymasz
TRUE
zwrot pieniędzy, nie oznacza to, że Twój e-mail na pewno zostanie wysłany. Oznacza to po prostu, że wiadomość e-mail została pomyślnie wysłana do odpowiedniego programu obsługi na serwerze przez PHP. Nadal istnieje więcej punktów awarii poza kontrolą PHP, które mogą spowodować, że wiadomość e-mail nie zostanie wysłana.
Więc FALSE
pomogą skierować Cię w dobrym kierunku, natomiast TRUE
ma nie musi oznaczać, e-mail został wysłany pomyślnie. Należy o tym pamiętać!
Upewnij się, że Twój dostawca usług hostingowych umożliwia wysyłanie wiadomości e-mail i nie ogranicza ich wysyłania
Wiele współdzielonych hostów internetowych, zwłaszcza darmowych dostawców usług hostingowych, albo nie zezwala na wysyłanie wiadomości e-mail ze swoich serwerów, albo ogranicza liczbę wysyłanych wiadomości w danym okresie. Wynika to z ich wysiłków na rzecz ograniczenia spamerom korzystania z ich tańszych usług.
Jeśli uważasz, że Twój usługodawca hostingowy ma ograniczenia dotyczące wysyłania e-maili lub blokuje wysyłanie e-maili, przejrzyj często zadawane pytania, aby sprawdzić, czy zawierają listę takich ograniczeń. W przeciwnym razie może być konieczne skontaktowanie się z ich pomocą techniczną, aby sprawdzić, czy istnieją jakieś ograniczenia dotyczące wysyłania wiadomości e-mail.
Sprawdź foldery ze spamem; zapobiegają oznaczaniu wiadomości e-mail jako spamu
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 sprawdź to przed przystąpieniem do rozwiązywania problemów z kodem.
Aby uniknąć wysyłania poczty wysyłanej za pośrednictwem PHP do folderu spamu odbiorcy, możesz zrobić różne rzeczy, zarówno w kodzie PHP, jak i w inny sposób, aby zminimalizować szanse, że Twoje wiadomości e-mail zostaną oznaczone jako spam. Dobre wskazówki od Michiel de Mare obejmują:
- Użyj metod uwierzytelniania poczty e-mail, takich jak SPF i DKIM, aby udowodnić, że Twoje wiadomości e-mail i nazwa domeny należą do siebie, oraz aby zapobiec podszywaniu się pod nazwę domeny. Witryna internetowa 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 adres IP, którego używasz, nie znajduje się na czarnej liście
- Upewnij się, że adres zwrotny jest prawidłowym, istniejącym adresem.
- Użyj pełnego, prawdziwego imienia i nazwiska adresata w polu Do, a nie tylko adresu e-mail (np
"John Smith" <[email protected]>
.).- Monitoruj swoje konta związane z nadużyciami, takie jak [email protected] i [email protected]. To znaczy - upewnij się, że te konta istnieją, przeczytaj, co do nich zostało wysłane, i zareaguj na skargi.
- Wreszcie, spraw, aby anulowanie subskrypcji było naprawdę łatwe. W przeciwnym razie Twoi użytkownicy zrezygnują z subskrypcji, naciskając przycisk spamu , a to wpłynie na Twoją reputację.
Zobacz artykuł Jak upewnić się, że wiadomości e-mail wysyłane programowo nie są automatycznie oznaczane jako spam? aby uzyskać więcej informacji na ten temat.
Upewnij się, że podano wszystkie nagłówki wiadomości
Niektóre programy spamujące odrzucają wiadomości e-mail, w których brakuje typowych nagłówków, takich jak „Od” i „Odpowiedź do”:
$headers = array("From: [email protected]",
"Reply-To: [email protected]",
"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. Jeden nieprawidłowy znak może wystarczyć, aby wykoleić e-mail. Sprawdź dokładnie, czy składnia jest poprawna, ponieważ PHP nie wyłapie tych błędów za Ciebie.
$headers = array("From [email protected]", // missing colon
"Reply To: [email protected]", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
Nie używaj fałszywego From:
nadawcy
Chociaż poczta musi mieć adres Od: nadawca, nie możesz po prostu użyć żadnej wartości. W szczególności adresy nadawców podane przez użytkownika są niezawodnym 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 pocztę nie znajduje się na białej liście SPF / DKIM, aby udawać, że jest odpowiedzialny za adresy @hotmail lub @gmail. Może nawet po cichu porzucić wiadomości 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 nieprawidłowej zmiennej.
$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
Innym sposobem na przetestowanie tego jest trwałe zakodowanie wartości odbiorcy w mail()
wywołaniu funkcji:
mail('[email protected]', $subject, $message, $headers);
Może to dotyczyć wszystkich mail()
parametrów.
Wyślij na wiele kont
Aby wykluczyć problemy z kontami e-mail, wyślij wiadomość e-mail na wiele kont e-mail u różnych dostawców poczty e-mail . Jeśli Twoje e-maile nie docierają na konto Gmail użytkownika, wyślij te same e-maile na konto Yahoo, konto 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 e-maile, ale jest prawdopodobne, że dostawca konta e-mail blokuje je z jakiegoś powodu. Jeśli wiadomość e-mail nie dotrze na żadne konto e-mail, problem jest prawdopodobnie związany z Twoim kodem.
Upewnij się, że kod jest zgodny z metodą formularza
Jeśli ustawiłeś metodę formularza na POST
, upewnij się, że używasz $_POST
do wyszukiwania wartości formularza. Jeśli ustawiłeś GET
lub w ogóle go nie ustawiłeś, upewnij się, że używasz $_GET
do wyszukiwania wartości formularza.
Upewnij się, że action
wartość formularza wskazuje prawidłową lokalizację
Upewnij się, że action
atrybut formularza zawiera wartość wskazującą na Twój kod pocztowy PHP.
<form action="send_email.php" method="POST">
Upewnij się, że host internetowy obsługuje wysyłanie wiadomości e-mail
Niektórzy dostawcy usług hostingowych nie zezwalają na wysyłanie wiadomości e-mail za pośrednictwem swoich serwerów ani nie pozwalają na to. Przyczyny tego mogą być różne, ale jeśli wyłączyli wysyłanie poczty, będziesz musiał użyć alternatywnej metody, która wykorzystuje stronę trzecią do wysyłania tych wiadomości e-mail za Ciebie.
Wiadomość e-mail do pomocy technicznej (po przejściu do pomocy online lub z często zadawanymi pytaniami) powinna wyjaśniać, czy funkcje poczty e-mail są dostępne na Twoim serwerze.
Upewnij się, że localhost
serwer pocztowy jest skonfigurowany
Jeśli programujesz na swojej lokalnej stacji roboczej przy użyciu WAMP, MAMP lub XAMPP, serwer poczty prawdopodobnie nie jest zainstalowany na Twojej stacji roboczej. Bez niej PHP nie może domyślnie wysyłać poczty.
Możesz temu zaradzić, instalując podstawowy serwer pocztowy. W przypadku systemu Windows można skorzystać z bezpłatnej poczty Mercury Mail .
Do wysyłania e-maili możesz także używać SMTP. Zobacz tę wielką odpowiedź od Vikas Dwivedi aby dowiedzieć się jak to zrobić.
Włącz niestandardowe pliki PHP mail.log
Oprócz pliku dziennika MTA i PHP możesz włączyć rejestrowanie specjalnie dla tej mail()
funkcji . Nie rejestruje całej 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źć pod adresem http://php.net/manual/en/mail.configuration.php . (Najlepiej jest włączyć te opcje w php.ini
lub .user.ini
lub .htaccess
być może).
Skontaktuj się z serwisem testującym pocztę
Istnieją różne usługi dostarczania i sprawdzania spamu, 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 bardziej konkretne awarie lub analizy później:
- mail-tester.com (darmowy / prosty)
- glockapps.com (darmowe / $$$)
- senforensics.com (rejestracja / $$$)
- mailtrap.io (pro / $$$)
- ultratools /… / emailTest (tylko czeki free / MX)
- Różne: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/
Użyj innej przesyłki
Wbudowana mail()
funkcja PHP jest przydatna i często wykonuje swoje zadanie, ale ma swoje wady . Na szczęście istnieją alternatywy, które oferują większą moc i elastyczność, w tym obsługują wiele problemów opisanych powyżej:
- Najpopularniejszy to: PHPMailer
- Podobnie funkcjonalny: SwiftMailer
- Albo nawet starszy PEAR :: Mail .
Wszystko to można połączyć z profesjonalnym serwerem / dostawcą usług SMTP. (Ponieważ typowe wspólne plany hostingu internetowego 08/15 są trafione lub nieudane, jeśli chodzi o konfigurację / konfigurowalność poczty e-mail).
Dodaj nagłówek wiadomości w funkcji poczty:
$header = "From: [email protected]\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>';
}
- Zawsze staraj się wysyłać nagłówki w funkcji poczty.
- Jeśli wysyłasz pocztę za pośrednictwem hosta lokalnego, skonfiguruj ustawienia SMTP dotyczące wysyłania poczty.
- Jeśli wysyłasz pocztę przez serwer, sprawdź, czy funkcja wysyłania wiadomości e-mail jest włączona na Twoim serwerze.
Jeśli używasz konfiguracji SMTP do wysyłania wiadomości e-mail, spróbuj zamiast tego użyć PHPMailer . Możesz pobrać bibliotekę z https://github.com/PHPMailer/PHPMailer .
Mój e-mail został utworzony 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 = "[email protected]";
$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";
}
Po prostu dodaj kilka nagłówków przed wysłaniem wiadomości:
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\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.
U mnie zadziałało 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 protected]', $subject, $message, $headers)
Użyj, ''
a nie ""
.
Ten kod działa, ale wiadomość e-mail została odebrana z półgodzinnym opóźnieniem.
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();
}
?>
Jeśli używasz tylko tej mail()
funkcji, musisz uzupełnić plik konfiguracyjny.
Musisz otworzyć rozszerzenie poczty, ustawić SMTP smtp_port
i tak dalej, a co najważniejsze, swoją nazwę użytkownika i hasło. Bez tego nie można wysłać poczty. Możesz także użyć PHPMail
klasy do wysłania.
Wypróbuj te dwie rzeczy osobno i razem:
- usunąć
if($_POST['submit']){}
- usuń
$from
(tylko moje wnętrzności)
Myślę, że to powinno załatwić sprawę. Właśnie dodałem if(isset
i dodałem konkatenację do zmiennych w treści, aby oddzielić PHP od HTML.
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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>';
}
}
?>
Dla każdego, kto odkryje to w przyszłości, nie polecam używania mail
. Jest kilka odpowiedzi, które dotykają tego, ale nie wyjaśniają dlaczego .
mail
Funkcja PHP jest nie tylko nieprzezroczysta, ale w pełni polega na tym, jakiego MTA używasz (np. Sendmail ) do wykonania pracy. mail
bę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. W związku z tym (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 niepowodzeniu w naprawie. Jeśli jesteś na wspólnym hoście lub nie masz dostępu do dzienników MTA, nie masz szczęścia. Niestety, domyślnie większość instalacji waniliowych dla Linuksa radzi sobie w ten sposób.
Biblioteka poczty ( PHPMailer , Zend Framework 2+ itp.) Robi coś zupełnie innego niż 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 (pamiętaj, że możesz powiedzieć bibliotekom, mail
aby ostatecznie wysłały pocztę, ale zdecydowanie odradzałbym tego).
Oznacza to, że możesz wtedy bezpośrednio zobaczyć odpowiedzi z serwera odbierającego (na przykład w PHPMailer możesz włączyć wyjście debugowania ). Koniec ze zgadywaniem, czy wiadomość nie została wysłana ani dlaczego.
Jeśli używasz SMTP (tj. Dzwonisz
isSMTP()
), możesz uzyskać szczegółową transkrypcję konwersacji SMTP za pomocąSMTPDebug
właściwości.Ustaw tę opcję, umieszczając taką linię w swoim skrypcie:
$mail->SMTPDebug = 2;
Zyskujesz także korzyści z lepszego interfejsu. Ze mail
trzeba ustawić wszystkie nagłówki, załączniki itp z biblioteki, masz dedykowaną funkcję, aby to zrobić. Oznacza to również, że funkcja wykonuje wszystkie trudne części (takie jak nagłówki).
$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>";
}
Możesz użyć e-maila konfiguracyjnego przez CodeIgniter . Na przykład używając 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' => '[email protected]',
'smtp_pass' => 'password',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('[email protected]', 'Title');
$this->email->to('[email protected]');
$this->email->subject('Header');
$this->email->message($message);
if($this->email->send())
{
// Conditional true
}
Mi to pasuje!
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>
';
}
}
Być może problemem jest konfiguracja serwera poczty. Aby uniknąć tego typu problemów lub nie musisz martwić się o problem z serwerem pocztowym, polecam użycie PHPMailera .
Jest to wtyczka, która ma wszystko, co niezbędne do wysyłania poczty, a jedyne, co musisz wziąć pod uwagę, to mieć włączony port 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 = '[email protected]';
$mail->Password = 'contrasenia';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
// Recipients
$mail->setFrom('[email protected]', 'my name');
$mail->addAddress('[email protected]');
// 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;
}
Upewnij się, że masz zainstalowany Sendmail na swoim serwerze.
Jeśli sprawdziłeś swój kod i potwierdziłeś, że nie ma tam 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.
Przede wszystkim możesz mieć zbyt wiele parametrów funkcji mail () ... Możesz mieć maksymalnie pięć, mail(to, subject, message, headers, parameters);
Jeśli chodzi o $from
zmienną, powinna ona automatycznie pochodzić od twojego hosta internetowego, jeśli używasz cPanel Linux . Automatycznie pochodzi z Twojej nazwy użytkownika i adresu IP cPanel.
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
Upewnij się również, że w funkcji mail () masz poprawną kolejność zmiennych.
W takiej kolejności, albo jest szansa, że nie zadziała.mail($to, $subject, $message, etc.)
Jeśli masz problemy z wysyłaniem maili z PHP, należy rozważyć alternatywę jak PHPMailer lub SwiftMailer .
Zwykle używam SwiftMailer, gdy chcę wysyłać pocztę 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('[email protected]' => 'Jane Doe'))
// The to address(es)
->setTo(array('[email protected]' => '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 ze SwiftMailer.
Dla tych, którzy nie chcą korzystać z zewnętrznych programów pocztowych i chcą wysyłać pocztę () na dedykowany serwer Linux.
Sposób, w jaki wysyłane są maile PHP, opisano php.ini
w rozdziale [mail function]
.
Parametr sendmail-path
opisuje, jak wywoływany jest sendmail. Wartość domyślna to sendmail -t -i
, więc jeśli dostaniesz pracę sendmail -t -i < message.txt
w konsoli Linuksa - skończysz. Możesz także dodać mail.log
do debugowania i upewnić się, że mail () jest naprawdę wywoływany.
Mogą być wdrażane różne umowy MTA sendmail
. Po prostu tworzą symboliczne dowiązanie do swoich plików binarnych o tej nazwie. Na przykład w Debianie domyślną wartością jest Postfix . Skonfiguruj MTA do wysyłania poczty i testuj ją z konsoli za pomocą sendmail -v -t -i < message.txt
. Plik message.txt
powinien zawierać wszystkie nagłówki wiadomości i treść, adres docelowy dla koperty zostanie pobrany z To:
nagłówka. Przykład:
From: [email protected]
To: [email protected]
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 nadaje się tylko do wysyłania poczty z lokalnego hosta . 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ć lokalną pocztę systemową na konta Unix (na przykład alerty do roota z zadań cron), należy skonfigurować /etc/ssmtp/revaliases
plik.
Oto moja konfiguracja mojego konta w poczcie Yandex:
[email protected]
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
[email protected]
AuthPass=password
Będzie to miało wpływ tylko na niewielką garstkę użytkowników, ale chciałbym, aby zostało to udokumentowane dla tej małej garstki. Ten członek tej małej garstki 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, który obsługuje XAMPP z www.AceITLab.com, powinieneś wiedzieć, czego nie powiedział nam nasz profesor: zapora sieciowa AceITLab (nie zapora systemu Windows) blokuje MercuryMail w XAMPP. Będziesz musiał użyć alternatywnego klienta pocztowego, gruszka pracuje dla nas. Będziesz musiał wysłać na konto Gmail z niskimi ustawieniami zabezpieczeń.
Tak, wiem, to jest całkowicie bezużyteczne w przypadku e-maili w prawdziwym świecie. Jednak z tego, co widziałem, środowisko akademickie i rzeczywisty świat często mają niewiele wspólnego.
Jeśli uruchamiasz ten kod na serwerze lokalnym (tj. Na komputerze do celów programistycznych), nie wyśle on wiadomości e-mail do odbiorcy. Utworzy .txt
plik w folderze o nazwie mailoutput
.
W przypadku, gdy korzystasz z bezpłatnej usługi hosing, takiej jak 000webhost
lub hostinger
, ci dostawcy usług wyłączają tę mail()
funkcję, aby zapobiec niezamierzonemu użyciu podszywania się pod wiadomości e-mail, spamowania itp. Wolę, abyś skontaktował się z nimi, aby sprawdzić, czy obsługują tę funkcję.
Jeśli jesteś pewien, że usługodawca obsługuje funkcję mail (), możesz zapoznać się z instrukcją PHP w celu uzyskania dalszych informacji,
Aby sprawdzić, czy Twój hosting obsługuje funkcję mail (), spróbuj uruchomić ten kod (pamiętaj o zmianie adresu e-mail odbiorcy) :
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
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)
Instalacja standardowego pakietu sendmaila (umożliwiająca 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 !
Możliwości jest kilka:
Masz problem z serwerem. Serwer nie posiada żadnego serwera pocztowego. Więc twoja poczta nie działa, ponieważ twój kod jest w porządku, a poczta działa z typem.
Nie otrzymujesz zaksięgowanej wartości. Wypróbuj swój kod ze stałą wartością.
Użyj wiadomości SMTP do wysyłania poczty ...
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 = '[email protected]'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = '[email protected]';
$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';
?>
Jeśli utkniesz z aplikacją hostowaną na Hostgatorze, to właśnie rozwiązało mój problem. Wielkie dzięki dla gościa, który przesłał szczegółowe rozwiązanie. W przypadku, gdy pewnego dnia link przejdzie w tryb offline, masz podsumowanie:
- Poszukaj ścieżki sendmaila na swoim serwerze. Prostym sposobem, aby to sprawdzić, jest tymczasowo napisać następujący kod w stronę, która tylko będzie można uzyskać dostęp, do zapoznania się z generowanych informacji:
<?php phpinfo(); ?>
. Otwórz tę stronę i wyszukajsendmail path
. (Następnie nie zapomnij usunąć tego kodu!) - Problem i napraw: jeśli twoja ścieżka do sendmaila mówi tylko
-t -i
, edytuj serwerphp.ini
i dodaj następujący wiersz:sendmail_path = /usr/sbin/sendmail -t -i;
Ale po tym, jak mogłem wysyłać pocztę z mail()
funkcją PHP , dowiedziałem się, że wysyła nie uwierzytelniony e-mail, co spowodowało kolejny problem. Wszystkie e-maile wpadały do skrzynki ze spamem mojego Hotmaila, a niektóre e-maile nigdy nie zostały dostarczone, co, jak sądzę, jest związane z faktem, że nie są uwierzytelnione. Dlatego zdecydowałem się przejść od mail()
do PHPMailer
z SMTP, mimo wszystko.