<?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>';
}
}
?>
Jeg har prøvet at oprette en simpel mailformular. Selve formularen er på min index.html
side, men den sender til en separat "tak for din indsendelse" side, thankyou.php
, hvor ovenstående PHP-kode er indlejret.
Koden indsendes perfekt, men sender aldrig en e-mail. Hvordan kan jeg løse dette?
Og selv om der er dele af dette svar, der kun gælder for brugen af selve funktionen mail()
, kan mange af disse fejlfindingstrin anvendes på ethvert PHP-mailing-system.
Der er en række forskellige årsager til, at dit script tilsyneladende ikke sender e-mails. Det er vanskeligt at diagnosticere disse ting, medmindre der er en åbenlys syntaksfejl. Uden en sådan skal du gennemgå nedenstående tjekliste for at finde eventuelle potentielle faldgruber, som du måske støder på.
Fejlrapportering er afgørende for at finde fejl i din kode og generelle fejl, som PHP støder på. Fejlrapportering skal være aktiveret for at modtage disse fejl. Hvis du placerer følgende kode øverst i dine PHP-filer (eller i en masterkonfigurationsfil), aktiveres fejlrapportering.
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
Se dette Stack Overflow-svar for flere detaljer om dette.
mail()
er kaldtDet kan virke fjollet, men en almindelig fejl er at glemme at placere mail()
-funktionen rent faktisk i din kode. Sørg for, at den er der og ikke kommenteret ud.
mail()
kaldes korrektbool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] ) Mailfunktionen tager tre nødvendige parametre og eventuelt en fjerde og femte parameter. Hvis dit kald til
mail()
ikke har mindst tre parametre, vil det mislykkes. Hvis dit kald tilmail()
ikke har de korrekte parametre i den korrekte rækkefølge, vil det også mislykkes.Tjek serverens maillogs
Din webserver bør logge alle forsøg på at sende e-mails gennem den. Placeringen af disse logfiler varierer (du skal måske spørge din serveradministrator, hvor de er placeret), men de kan normalt findes i en brugers rodmappe under
logs
. Indeni vil der være fejlmeddelelser, som serveren har rapporteret, hvis der er nogen, der er relateret til dine forsøg på at sende e-mails.Kontroller, om der er fejl i portforbindelsen
Portblokering er et meget almindeligt problem, som de fleste udviklere står over for, mens de integrerer deres kode til at levere e-mails ved hjælp af SMTP. Og dette kan let spores i serverens maillogs (placeringen af serveren for maillog kan variere fra server til server, som forklaret ovenfor). Hvis du er på en delt hosting-server, forbliver portene 25 og 587 blokeret som standard. Denne blokering er bevidst foretaget af din hostingudbyder. Dette gælder også for nogle af de dedikerede servere. Når disse porte er blokeret, skal du forsøge at oprette forbindelse ved hjælp af port 2525. Hvis du finder ud af, at denne port også er blokeret, er den eneste løsning at kontakte din hostingudbyder for at få ophævet blokeringen af disse porte. De fleste hostingudbydere blokerer disse e-mail-porte for at beskytte deres netværk mod at sende spammails. Brug port 25 eller 587 til almindelige/TLS-forbindelser og port 465 til SSL-forbindelser. For de fleste brugere anbefales det at bruge port 587 for at undgå hastighedsbegrænsninger, som nogle hostingudbydere har fastsat.
Brug ikke fejlundertrykkelsesoperatoren
Når error suppression operator
@
indsættes i et udtryk i PHP, ignoreres alle fejlmeddelelser, som måtte blive genereret af det pågældende udtryk. Der er omstændigheder, hvor det er nødvendigt at bruge denne operatør, men at sende post er ikke en af dem. Hvis din kode indeholder@mail(...)
, så skjuler du måske vigtige fejlmeddelelser, som vil hjælpe dig med at fejlfinde dette. Fjern@
og se, om der bliver rapporteret nogen fejl. Det'er kun tilrådeligt, når du kontrollerer mederror_get_last()
lige bagefter for konkrete fejl.Kontroller
mail()
s returværdifunktionen
mail()
: ReturnererTRUE
, hvis mailen blev accepteret til levering,FALSE
ellers. Det er vigtigt at bemærke, at bare fordi mailen blev accepteret til levering, betyder det IKKE, at mailen rent faktisk når frem til den tilsigtede destination. Dette er vigtigt at bemærke, fordi:
- Hvis du modtager en
FALSE
returværdi, ved du at fejlen ligger i at din server accepterer din mail. Dette er sandsynligvis ikke et kodningsproblem, men et problem med serverkonfigurationen. Du skal tale med din systemadministrator for at finde ud af, hvorfor dette sker.- Hvis du modtager en
TRUE
returværdi, betyder det ikke, at din e-mail helt sikkert bliver sendt. Det betyder blot, at PHP har sendt e-mailen til den respektive håndtering på serveren med succes. Der er stadig flere fejlpunkter uden for PHP's kontrol, som kan medføre, at e-mailen ikke bliver sendt. SåFALSE
vil hjælpe dig med at pege dig i den rigtige retning, mensTRUE
ikke nødvendigvis betyder, at din e-mail blev sendt med succes. Dette er vigtigt at bemærke!Sørg for, at din hostingudbyder tillader dig at sende e-mails og ikke begrænser mailforsendelsen
Mange delte webhoteller, især gratis webhosting-udbydere, tillader enten ikke at sende e-mails fra deres servere eller begrænser mængden af e-mails, der kan sendes i løbet af en given tidsperiode. Dette skyldes, at de forsøger at begrænse spammere fra at udnytte deres billigere tjenester. Hvis du tror, at din host har begrænsninger for e-mailing eller blokerer for afsendelse af e-mails, så tjek deres FAQ'er for at se, om de oplyser om sådanne begrænsninger. Ellers skal du måske kontakte deres support for at kontrollere, om der er nogen begrænsninger omkring afsendelse af e-mails.
Kontroller spam-mapper; undgå, at e-mails bliver markeret som spam
Ofte ender e-mails, der sendes via PHP (og andre server-side programmeringssprog) af forskellige årsager i en modtagers spam-mappe. Tjek altid der, før du fejlfinder din kode. For at undgå, at e-mails sendt via PHP bliver sendt til en modtagers spam-mappe, er der forskellige ting, du kan gøre, både i din PHP-kode og på anden vis, for at minimere chancerne for, at dine e-mails bliver markeret som spam. Gode tips fra Michiel de Mare omfatter bl.a:
- Brug e-mail-godkendelsesmetoder, såsom SPF og DKIM for at bevise, at dine e-mails og dit domænenavn hører sammen, og for at forhindre spoofing af dit domænenavn. SPF-webstedet indeholder en guide til at generere DNS-oplysningerne for dit websted.
- Check din reverse DNS for at sikre, at IP-adressen på din mailserver peger på det domænenavn, du bruger til at sende mails.
- Sørg for, at den IP-adresse, du bruger, ikke er på en sortliste
- Sørg for, at reply-to adressen er en gyldig, eksisterende adresse.
- Brug adressatens fulde, rigtige navn i feltet To, ikke kun e-mail-adressen (f.eks.
"John Smith" <[email protected]>
).- Overvåg dine misbrugskonti, f.eks. [email protected] og [email protected]. Det vil sige - sørg for, at disse konti findes, læs, hvad der sendes til dem, og reager på klager.
- Endelig skal du gøre det virkelig nemt at afmelde sig. Ellers vil dine brugere afmelde sig ved at trykke på spam-knappen, og det vil påvirke dit omdømme. Se [Hvordan sikrer du dig, at e-mail, du sender programmatisk, ikke automatisk markeres som spam?] (https://stackoverflow.com/q/371/250259) for at få mere at vide om dette emne.
Sørg for, at alle mailheadere er leveret
Nogle spamprogrammer afviser mails, hvis der mangler almindelige overskrifter som f.eks. "From" og "Reply-to":
$headers = array("From: [email protected]",
"Reply-To: [email protected]",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
Ugyldige headers er lige så slemt som at have ingen headers. Et enkelt forkert tegn kan være alt, hvad der skal til for at afspore din e-mail. Dobbelttjek, at din syntaks er korrekt, da PHP ikke opfanger disse fejl for dig.
$headers = array("From [email protected]", // missing colon
"Reply To: [email protected]", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
From:
senderSelvom mailen skal have en From: afsender, må du ikke bare bruge nogle værdier. Især brugerindtastede afsenderadresser er en sikker måde at få mails blokeret på:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Årsag: Din web- eller afsendende mailserver er ikke SPF/DKIM-whitelistet for at foregive at være ansvarlig for @hotmail- eller @gmail-adresser. Den kan endda stille og roligt droppe mails med From:
-afsenderdomæner, som den ikke er konfigureret til.
Nogle gange er problemet så simpelt som at have en forkert værdi for modtageren af e-mailen. Det kan skyldes, at der er brugt en forkert variabel.
$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
En anden måde at teste dette på er at hardcode modtagerværdien i mail()
-funktionskaldet:
mail('[email protected]', $subject, $message, $headers);
Dette kan gælde for alle parametre i mail()
.
For at hjælpe med at udelukke problemer med e-mailkonti kan du sende din e-mail til flere e-mailkonti på forskellige e-mailudbydere. Hvis dine e-mails ikke ankommer til en brugers Gmail-konto, så send de samme e-mails til en Yahoo-konto, en Hotmail-konto og en almindelig POP3-konto (f.eks. din internetudbyders e-mailkonto). Hvis e-mailene ankommer til alle eller nogle af de andre e-mailkonti, ved du, at din kode sender e-mails, men det er sandsynligt, at udbyderen af e-mailkontoen blokerer dem af en eller anden grund. Hvis e-mailen ikke ankommer til nogen e-mailkonto, er det mere sandsynligt, at problemet er relateret til din kode.
Hvis du har sat din formularmetode til POST
, skal du sikre dig, at du bruger $_POST
til at søge efter dine formularværdier. Hvis du har indstillet den til GET
eller slet ikke har indstillet den, skal du sørge for, at du bruger $_GET
til at søge efter dine formularværdier.
action
-værdi peger på det rigtige stedSørg for, at din formular action
-attribut indeholder en værdi, der peger på din PHP-mailingkode.
<form action="send_email.php" method="POST">
Nogle webhostingudbydere tillader eller tillader ikke, at der sendes e-mails via deres servere. Årsagerne til dette kan variere, men hvis de har deaktiveret afsendelse af e-mails, skal du bruge en alternativ metode, der bruger en tredjepart til at sende disse e-mails for dig. En e-mail til deres tekniske support (efter en tur til deres online support eller FAQ) bør afklare, om e-mailfunktioner er tilgængelige på din server.
localhost
-mailserveren er konfigureretHvis du udvikler på din lokale arbejdsstation ved hjælp af WAMP, MAMP eller XAMPP, er der sandsynligvis ikke installeret en e-mail-server på din arbejdsstation. Uden en sådan kan PHP som standard ikke sende mail. Du kan afhjælpe dette ved at installere en grundlæggende mailserver. Til Windows kan du bruge den gratis [Mercury Mail] (http://www.pmail.com/overviews/ovw_mercury.htm). Du kan også bruge SMTP til at sende dine e-mails. Se dette gode svar fra Vikas Dwivedi for at lære, hvordan du gør dette.
mail.log
Ud over din MTA's og PHP's logfil kan du aktivere logning for funktionen mail()
specifikt. Det registrerer ikke hele SMTP-interaktionen, men i det mindste funktionskaldsparametre og scriptet for kald af funktionen.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
Se http://php.net/manual/en/mail.configuration.php for yderligere oplysninger. (Det'er bedst at aktivere disse muligheder i php.ini
eller .user.ini
eller .htaccess
måske).
Der findes forskellige tjenester til kontrol af levering og spam, som du kan bruge til at teste din MTA/webserveropsætning. Typisk sender du en mail probe To: deres adresse, og får så en leveringsrapport og mere konkrete fejl eller analyser senere:
PHP's indbyggede mail()
-funktion er praktisk og klarer ofte opgaven, men den har sine mangler. Heldigvis findes der alternativer, der giver mere kraft og fleksibilitet, herunder håndtering af mange af de problemer, der er skitseret ovenfor:
Hvis du bruger en SMTP-konfiguration til at sende din e-mail, kan du prøve at bruge PHPMailer i stedet. Du kan downloade biblioteket fra https://github.com/PHPMailer/PHPMailer.
Jeg oprettede min e-mail-afsendelse på denne måde:
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";
}
Du skal blot tilføje nogle overskrifter, før du sender mailen:
<?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);
Og en ting mere. Funktionen mail()
virker ikke på localhost. Upload din kode til en server og prøv.