PHP-mailfunktionen afslutter ikke afsendelse af e-mail

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

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å.

Sørg for, at fejlrapportering er aktiveret og indstillet til at rapportere alle fejl

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.

Sørg for, at funktionen mail() er kaldt

Det 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.

Sørg for, at funktionen mail() kaldes korrekt

bool 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 til mail() 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 med error_get_last() lige bagefter for konkrete fejl.

Kontroller mail()s returværdi

funktionen mail(): Returnerer TRUE, 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, mens TRUE 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" ).
  • Overvåg dine misbrugskonti, f.eks. abuse@yourdomain.com og postmaster@yourdomain.com. 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: from@example.com",
    "Reply-To: replyto@example.com",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);

Sørg for, at der ikke er syntaksfejl i mailheaders

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 from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Don't use a faux From: sender

Selvom 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.

Sørg for, at modtagerværdien er korrekt

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 = 'user@example.com';
// 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('user@example.com', $subject, $message, $headers); 

Dette kan gælde for alle parametre i mail().

Send til flere konti

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.

Sørg for, at koden passer til formularmetoden

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.

Sørg for, at din formular action-værdi peger på det rigtige sted

Sørg for, at din formular action-attribut indeholder en værdi, der peger på din PHP-mailingkode.

Sørg for, at webhotellet understøtter afsendelse af e-mail

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.

Sørg for, at localhost-mailserveren er konfigureret

Hvis 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.

Aktiver PHP's brugerdefinerede 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).

Kontroller med en mailtesttjeneste

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:

Kommentarer (7)

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 = "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";
}
Kommentarer (1)

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 = '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);

Og en ting mere. Funktionen mail() virker ikke på localhost. Upload din kode til en server og prøv.

Kommentarer (3)