Att skicka mail via PHP

Att skicka mail är en viktig del av ganska många applikationer och webbsidor. Och målet är ju självklart att någon faktiskt ska läsa mailet, och inte att ett spamfilter ska plocka bort mailet. Spamfilter är dock tyvärr nödvändiga med den mängd spam som skickas idag, och det har därför blivit allt viktigare att skicka mail som är korrekt formaterade, följer gällande standarder och har ett innehåll som inte verkar “spammigt”. I detta blogginlägget tänkte vi dela med oss av en del tips gällande detta. Vi tänkte också berätta lite om de krav som vårt utgående spamfilter ställer på mail som skickas från webbhotellskonton hos oss.

Vårt spamfilter

Vi spamfiltrerar samtliga mail som skickas från våra webbhotells-kunder. Detta gör vi för att då det är en delad miljö och många kunder delar på samma resurser så ska ingen kund kunna förstöra för andra genom att få servrarna svartlistade av andra leverantörer och de blocklistor som dessa använder. Nu tror vi ju självklart inte att våra kunder med avsikt skickar spam, men vi kan tyvärr inte lita blint på det. Det kan t.ex. vara en kund som får intrång i sin webbsida och att den därför används för att skicka spam eller t.ex. ett e-postformulär som inte är säkert nog. Därför ställer vi en del krav på de mail som skickas, enkelt summerat är det följande krav.

  • Mottagardomänen måste existera
  • Avsändare måste vara en korrekt e-postadress
  • Avsändaren får inte vara en av våra serveradresser

Utöver detta så virus-skannas alla mail och kontrolleras med en mjukvara som heter SpamAssassin. Den senare gör en hel del olika tester och mailet får olika hög poäng beroende på hur många, och vilka av dessa tester som ger träff på mailet. Om mailet får en för hög poäng så räknas det som spam och släpps inte igenom. Något som ganska fort ger en hög poäng nog för att mail ska klassas som spam är att inte skicka korrekta mail. Det vill säga mail som inte innehåller ämne, datum, meddelande-id eller en korrekt satt avsändare eller mottagare. Om man skickar mail med HTML-kod i så bör man även tänka på korrekt MIME-formatering. Man behöver även tänka på kodningen av specialtecken som t.ex. å ä och ö.

PHPMailer

Om man vill göra det enkelt för sig så kan man använda sig utav en färdig klass som heter PHPMailer. Den fungerar som ett lager mellan mailfunktionerna i PHP och din egen kod, ger dig ett enklare gränssnitt och hjälper dig att få till korrekta mail. PHPMailer kan du ladda ner här. Ett exempel på hur man kan använda PHPMailer följer nedan.

SetFrom($sender, $sendername);
$pm->AddReplyTo($sender, $sendername);
$pm->Sender = $pm->From;
$pm->AddAddress($recipient, $recipientname);

// Sätt ämne och meddelande
$pm->Subject = "Mitt ämne";
$pm->Body = "Innehållet i mailet";

// Skicka
if(!$pm->Send()) {
    echo "Mail kunde ej skickas: " . $mail->ErrorInfo;
}
else {
    echo "Mailet har skickats!";
}

WordPress

Kör man WordPress som nog är den absolut vanligaste applikationen idag för både bloggar och mängder med andra typer av webbsidor så sköter WordPress skickandet av mail med inbyggda funktioner. Dock missar WordPress en punkt. Som standard skickar nämligen WordPress mail utan att sätta en korrekt avsändare, vilket innebär att mailen skickas från @servernamn.citynetwork.se. Det finns inget sätt att ändra på detta mer än att ändra källkoden till WordPress vilket skulle göra det ganska omständigt att uppdatera WordPress, alternativt genom att lägga till lite PHP-kod i sitt tema.

För att göra det lite enklare har vi därför tagit fram ett litet plugin som löser detta åt dig. Det enda du behöver göra är att ladda ner vårt plugin, installera och aktivera detta så är det klart sedan. Det installeras precis som vilket annat plugin som helst, och kommer börja fungera direkt efter aktivering i WordPress-administrationen. Någon konfiguration behövs inte.

Använda mail() i PHP

För de som utvecklar egna skript som skickar mail och inte vill använda t.ex. PHPMailer så har vi även ett exempel på hur man kan göra för att skicka mail lite mera “manuellt”. Här behöver man själv tänka på de flesta headers, att man använder rätt encoding och man anropar själv PHP’s mailfunktioner. Det finns dock en hel del inbyggt i PHP som man kan använda för att inte behöva göra allt själv. Nedan har vi ett exempel på hur man kan göra för att skicka mail på detta viset, notera dock att det enbart är ett exempel och att det finns massor med andra olika vis man kan göra detta på. Notera också att vi använder funktionen mb_send_mail() istället för mail() då det underlättar något för mail som innehåller t.ex. å ä eller ö.

";

// Ställ in rätt kodningstyp
mb_internal_encoding("UTF-8");

// Rätt kodning för avsändare och mottagares namn
$sendername = mb_encode_mimeheader($sendername);
$recipientname = mb_encode_mimeheader($recipientname);

// Sätt headers
$headers =<<
Date: $date
Message-ID: $mid
MIME-Version: 1.0 
Content-Type: text/plain; charset="UTF-8"
EOT;

// Skicka mail
$status = mb_send_mail("$recipientname <$recipient>", $subject, $message, $headers, "-f$sender");
if(!$status) {
        echo "Mail kunde inte skickas.";
}
else {
        echo "Mail skickat!";
}

  • Tim

    Tack för inlägget! Det andra exemplet kommer jag själv att prova.

  • Torgil

    Kan du förtydliga följande:

    Avsändare måste vara en korrekt e-postadressInnebär det att avsändaren måste vara en fungerande e-postadress? Eller bara att den ska vara formaterad som en korrekt e-postadress?Avsändaren får inte vara en av våra serveradresserVad menas med detta? 

    • https://www.citysites.se/ Özgur Bal

      Med det menas att det måste vara en korrekt formaterad e-postadress, och den måste tillhöra en aktiv domän. Dessutom måste du sätta en egen avsändaradress, du får inte skicka från standard-avsändaren i PHP som är användare@server.citynetwork.se, utan måste sätta en egen adress. Hur du gör detta kan du se i exemplen ovan.

  • Kristofer

    När jag kollar vårt nyhetsbrev mot en spamkollartjänst så får jag denna varningen om reverse dns lookup:
    Your IP 91.123.193.92 is associated with the domain mailout01.citynetwork.se.Nevertheless your message appears to be sent from “mailout.citynetwork.se”.

    • https://citynetwork.se/ Johan Hedberg

      Hej,

      Vilken tjänst var det som du kollade detta mot? Så kan vi kika på vad det kan bero på.

      • Kristofer

        Det är http://www.mail-tester.com

  • Christer Johansson

    Bra artikel! Jag undrade precis varför min WP inte skickade mailen till mig. Pluggen fungerade vid första försöket! (Kör WP 3.8 med GravityForms).

  • Mikael Lindström

    Jag försöker skicka till flera mottagare. Har prövat med följande.
    Vet någon hur jag skall göra?

    //Micke
    $recipient =”kalle.kula@kula.se” . “,” . “Nisse.kula@kula.se”; Fungerar inte.
    $recipient =”kalle.kula@kula.se, Nisse.kula@kula.se“; Fungerar inte

    $recipient =”kalle.kula@kula.se” . “;” . “Nisse.kula@kula.se”; Fungerar inte.
    $recipient =”kalle.kula@kula.se; Nisse.kula@kula.se“; Fungerar inte

    • Johan Hedberg

      Hej Mikael,

      Det ska fungera att sätta kommatecken mellan mottagar-adresserna enligt dokumentationen för mb_send_mail() här: http://se1.php.net/mb_send_mail

      Normalt sett vill man dock inte göra detta då mottagarna kommer att se varandras adresser. Därför gör man oftast en loop över en array av mottagare och skickar ett mail för varje mottagare.

      Exempelvis något åt det här hållet:

      $recipients = array(‘kalle.kula@kula.se’, ‘nisse.kula@kula.se’);
      foreach($recipients as $recipient) {
      $status = mb_send_mail($recipient, $subject, $message, $headers, “-f$sender”);
      }

  • Hasse Roine

    Funkade direkt efter installationen av plugin i WP! Gäller detta problem även hos andra ISP eller har ni hårdare spam-koll rent generellt? Flyttar ju ofta sajter mellan olika ISP.