Paul K.: php mail() funktioniert unzuverlässig...

hallo,

ich habe gerade entdeckt, dass meine mail() Funktion unzuverlässig ist. Manche Mails werden zugestellt, andere nicht. Ich habe das skript so eingerichtet, dass es eine Bestätigung an den Absender und gleichzeitig die Mail an mich sendet. Auf der Website wird eine Bestätigung bei erfolgreichem Versand angezeigt. Eigenartig ist, dass der Erfolg bestätigt wird, auch wenn nur eine der beiden Mails ankommt, weshalb ich eigentlich davon ausgehen muss, dass auch die zweite Mail zumindest aus der Sicht des Scripts erfolgreich versandt wurde. Ich habe auch schon probiert, an eine andere Adresse zu versenden, es bleibt jedoch dabei, dass es manchmal klappt und manchmal nicht, einmal wird nur die Bestätigung an den Sender, ein andermal nur die Email an mich versendet, manchmal auch keine der beiden oder beide. Ich bilde mir ein, dass es früher sehr stabil funktioniert hat. Änderungen am Server habe ich aber seither keine vorgenommen. Der Webhoster hat auf meine Anfrage (noch?) nicht reagiert. Daher hier meine Fragen:

  1. Gibt es eine Möglichkeit, in php ein Logfile auszulesen, das mir alle vergangenen Sendeversuche anzeigt?
  2. Was kann ich verändern??

Danke!

Anbei noch die relevante Zeile aus meinem php-Script:

if (mail('office@test.com','Nachricht von '.$_POST['vorname'].' '.$_POST['nachname'],stripslashes($_POST['message']), $extra)
and mail($_POST['email'],'Kopie Ihrer Nachricht ',stripslashes($_POST['message']), $extra)){
echo"<br /><div id='erfolg'>Ihre Nachricht wurde versendet.<br />Sie erhalten eine Bestätigung an Ihre Emailadresse ".$_POST['email_v'].' .</div>';  }
else echo"Fehler beim Senden der Nachricht. Bitte Probieren Sie es zu einem späteren Zeitpunkt oder kontaktieren sie uns per <a href='kontakt.php'>Telefon</a>.";

}
  1. n'Abend,

    ich habe gerade entdeckt, dass meine mail() Funktion unzuverlässig ist.

    na, herzlichen Glückwunsch. ;-)

    Manche Mails werden zugestellt, andere nicht.

    Ja. Die PHP-Funktion mail() tut auch nichts weiter, als die Mailnachricht in die Warteschlange zum Versand einzureihen. Wenn das gelingt, meldet die Funktion "Erfolg". Über das Versenden an sich erfährst du aber nichts mehr.

    Ich habe das skript so eingerichtet, dass es eine Bestätigung an den Absender und gleichzeitig die Mail an mich sendet. Auf der Website wird eine Bestätigung bei erfolgreichem Versand angezeigt. Eigenartig ist, dass der Erfolg bestätigt wird, auch wenn nur eine der beiden Mails ankommt, weshalb ich eigentlich davon ausgehen muss, dass auch die zweite Mail zumindest aus der Sicht des Scripts erfolgreich versandt wurde.

    Ja: Sie wurde erfolgreich zum Versand gegeben.

    1. Gibt es eine Möglichkeit, in php ein Logfile auszulesen, das mir alle vergangenen Sendeversuche anzeigt?

    Nein. Da müsstest du eher das Log deines MTA befragen, wenn es ein solches gibt.

    1. Was kann ich verändern??

    Du könntest den kompletten SMTP-Dialog selbst realisieren. Das möchte man aber normalerweise nicht. Denn auch wenn das SMTP-Protokoll eigentlich recht einfach ist, liegt der Teufel im Detail. Sogar in mehreren Details.

    if (mail('office@test.com','Nachricht von '.$_POST['vorname'].' '.$_POST['nachname'],stripslashes($_POST['message']), $extra)
    and mail($_POST['email'],'Kopie Ihrer Nachricht ',stripslashes($_POST['message']), $extra)){
    echo"<br /><div id='erfolg'>Ihre Nachricht wurde versendet.<br />Sie erhalten eine Bestätigung an Ihre Emailadresse ".$_POST['email_v'].' .</div>';  }
    else echo"Fehler beim Senden der Nachricht. Bitte Probieren Sie es zu einem späteren Zeitpunkt oder kontaktieren sie uns per <a href='kontakt.php'>Telefon</a>.";
    }
    

    Die Verwendung der Funktion stripslashes() ist ein Indiz, dass du noch etwas anderes gravierend falsch machst. Und erst recht die Tatsache, dass du POST-Parameter ungeprüft verwendest. Da könnte man dir sonstwas unterjubeln.

    So long,
     Martin

    --
    Computer müssen weiblich sein: Eigensinnig, schwer zu durchschauen, immer für Überraschungen gut - aber man möchte sie nicht missen.
  2. Hello,

    hallo,

    ich habe gerade entdeckt, dass meine mail() Funktion unzuverlässig ist. Manche Mails werden zugestellt, andere nicht. Ich habe das skript so eingerichtet, dass es eine Bestätigung an den Absender und gleichzeitig die Mail an mich sendet. Auf der Website wird eine Bestätigung bei erfolgreichem Versand angezeigt. Eigenartig ist, dass der Erfolg bestätigt wird, auch wenn nur eine der beiden Mails ankommt, weshalb ich eigentlich davon ausgehen muss, dass auch die zweite Mail zumindest aus der Sicht des Scripts erfolgreich versandt wurde. Ich habe auch schon probiert, an eine andere Adresse zu versenden, es bleibt jedoch dabei, dass es manchmal klappt und manchmal nicht, einmal wird nur die Bestätigung an den Sender, ein andermal nur die Email an mich versendet, manchmal auch keine der beiden oder beide. Ich bilde mir ein, dass es früher sehr stabil funktioniert hat. Änderungen am Server habe ich aber seither keine vorgenommen. Der Webhoster hat auf meine Anfrage (noch?) nicht reagiert. Daher hier meine Fragen:

    1. Gibt es eine Möglichkeit, in php ein Logfile auszulesen, das mir alle vergangenen Sendeversuche anzeigt?
    2. Was kann ich verändern??

    Danke!

    Anbei noch die relevante Zeile aus meinem php-Script:

    if (mail('office@test.com','Nachricht von '.$_POST['vorname'].' '.$_POST['nachname'],stripslashes($_POST['message']), $extra)
    and mail($_POST['email'],'Kopie Ihrer Nachricht ',stripslashes($_POST['message']), $extra)){
    echo"<br /><div id='erfolg'>Ihre Nachricht wurde versendet.<br />Sie erhalten eine Bestätigung an Ihre Emailadresse ".$_POST['email_v'].' .</div>';  }
    else echo"Fehler beim Senden der Nachricht. Bitte Probieren Sie es zu einem späteren Zeitpunkt oder kontaktieren sie uns per <a href='kontakt.php'>Telefon</a>.";
    
    }
    

    Dazu gibt es viel zu schreiben, von Mailinjection über Codierung zur Funktionsweise des Mailwrappers von PHP (Zusammenarbeif mif dem Mailserver), Zeilenumbrüche, ...

    Morgen bekommst Du Antwort von mir.

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  3. Hallo Paul,

    wichtige Punkte hat dir Martin schon genannt. Bei deinem Problem würde ich von einer Servereinstellung ausgehen. Vielleicht greift hier ab und zu eine Sicherheitssperre. Deine IF würde ich mal umbauen und sehen was passiert. (nehme jetzt der Einfachheit deine Werte, obwohl Martin dir ja schon was dazu gesagt hat). Sehe auch gerade mit den Hochkommata ist etwas chaotisch und übersichtlicher sowieso getrennt.

    $empf_1 = 'office@test.com';
    $betreff_1 = "Nachricht von {$_POST['vorname']} {$_POST['nachname']}"; 
    $mess = stripslashes($_POST['message']);
    
    $empf_2 = $_POST['email'];
    $betreff_2 = 'Kopie Ihrer Nachricht';
    
    if( mail($empf_1,$betreff_1,$mess, $extra) )
    {
    
    // Nur mal testen, ob vielleicht eine kleine Verzögerung was bringt
    sleep(1);
    
    mail($empf_2,$betreff_2,$mess, $extra);
    
    echo"<br /><div id='erfolg'>Ihre Nachricht wurde versendet.<br />Sie erhalten eine Bestätigung an Ihre Emailadresse ".$_POST['email_v'].' .</div>';
    
    }else{
    
    echo "
    Fehler beim Senden der Nachricht.
    Bitte Probieren Sie es zu einem späteren Zeitpunkt
    oder kontaktieren sie uns per <a href='kontakt.php'>Telefon</a>.";
    } 
    
    

    Mal abgesehen von der Verzögerung, ist die Kontrollmail nun innerhalb der bestätigten Mailaufforderung (weil, wofür zusätzliche Kontrolle), falls doch kannst du das ja wieder so machen wie bisher nur (als Anregung) vielleicht mit "&&" anstatt "and". Frag mich nicht warum, habs mir so angewöhnt, weils mir igendwann mal gesagt wurde, weils in der Rangordnung höher steht und mir persönlich besser zusagt, echte Vorteile, anhand Beispiele, müsste jemand anders erklären.

    ps. Die aktuelle Darstellung vom Quellcode, bedingt durch die extrascrollbalken ist nicht schön. Ich vermute ich kann das für meine Ansicht im CSS ändern, für normale besucher wärs vielleicht besser wenn zumindest die Schrift darin kleiner wäre, damits den Post nicht so erschlägt und übersichtlicher erscheint? Nur ne Anregung.

    Gruss
    Henry

    --
    Meine Meinung zu DSGVO & Co:
    „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
    1. Hello,

      zuerst das mail.log und das zugehörige Errorlog befragen.

      Und dann ist der Fehler erfahrungsgemäß bei falscher oder fehlender Codierung/Codierungsangabe, sowie ggf. falschen EOL zu suchen.

      Außerdem gehört der Kontroll-Emailname in einen bcc-Header für die eMail. Nur so ist sicherzustellen, dass der Mailserver beide eMails gleich behandelt - mit Ausnahme der Adressaten.

      Adressaten direkt aus Benutzereingaben in die Mailheader zu übernehmen, gehört außerdem mit Internetverbot bestraft!

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
      1. zuerst das mail.log und das zugehörige Errorlog befragen.

        wo finde ich denn diese Logdateien? in meinenm Root-verzeichnis finde ich einen "Stats" - Ordner, sonst aber keinerlei zusätzliche Ordner und Datein ausser den von mir angelegten.

        Und dann ist der Fehler erfahrungsgemäß bei falscher oder fehlender Codierung/Codierungsangabe, sowie ggf. falschen EOL zu suchen.

        Was meinst du mit Codierung? Wo gehört da was hin? Innerhalb der mail()-Funktion? Da hab ich nur noch stehen: $extra .= "Content-Type: text/html\n;"

        Außerdem gehört der Kontroll-Emailname in einen bcc-Header für die eMail. Nur so ist sicherzustellen, dass der Mailserver beide eMails gleich behandelt - mit Ausnahme der Adressaten.

        du meinst also, garnicht zwei Mails zu verschicken, sondern nur eines und Bcc an mich?

        Adressaten direkt aus Benutzereingaben in die Mailheader zu übernehmen, gehört außerdem mit Internetverbot bestraft!

        Ich habe das weiter unten schon beschrieben: Die Inhalte der Eingabefelder werden vorab geprüft eund bei Plausibilität als Vorschau dargestellt, die dann manuell per Usereingabe bestätigt wird. Genügt das so?

        Glück Auf
        Tom vom Berg

        1. wo finde ich denn diese Logdateien?

          Auf Linux oder Unix-Systemen unterhalb von /var/log/.

          in meinenm Root-verzeichnis finde ich einen "Stats" - Ordner, sonst aber keinerlei zusätzliche Ordner und Datein ausser den von mir angelegten.

          Dein Hoster hat Dich in einer "chroot-Umgebung" eingesperrt. (Das hätte ich mit Dir wohl auch so gemacht.) Also kommst Du, jedenfalls nicht ohne besondere Kenntnisse, nicht an die Logfiles ran. Aber der Kundendienst Deines Hosters kann diese (hoffentlich) lesen…

          Im Hinblick auf Dein Skript würde es mich nicht wundern wenn da ab und an bei einigen Mailservern eine Firewall und/oder ein (die Firewall steuernder) Spamfilter Mails vom Server Deines Hosters nicht mehr will. Du schädigst also mutmaßlich noch hunderte oder gar tausende andere Kunden Deines Hosters.

          1. Gibts vielleicht irgendwo eine Anleitung oder ein Beispiel für ein richtig implementiertes php - Kontaktformular, das mail() benutzt?

            Im Hinblick auf Dein Skript würde es mich nicht wundern wenn da ab und an bei einigen Mailservern eine Firewall und/oder ein (die Firewall steuernder) Spamfilter Mails vom Server Deines Hosters nicht mehr will. Du schädigst also mutmaßlich noch hunderte oder gar tausende andere Kunden Deines Hosters.

            1. Hallo Paul,

              Gibts vielleicht irgendwo eine Anleitung oder ein Beispiel für ein richtig implementiertes php - Kontaktformular, das mail() benutzt?

              Du möchtest das also als Kontaktformular nutzen? Warum dann eine Email an der Ersteller? Wobei sowas sowieso oft schon keine gute Idee ist, denn wenn du keinen ordentlichen Spamschutz hinbekommst, könntest du zugemüllt werden. Früher gehörte ein Kontaktformular zum guten Ton, mittlerweile hat sich, eben aus den Gründen, eine einfache Emailadresse durchgesetzt.

              Was hat eigentlich der Test mit sleep() ergeben?

              Was du vielleicht suchst, sind sogenannte Ticketsysteme zb. das hier. Lohnt sich aber nicht die Mühe bei wenigen Anfragen.

              Gruss
              Henry

              --
              Meine Meinung zu DSGVO & Co:
              „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
        2. Hello,

          für die Kodierung der Header gibt es eine Funktion mb_encode_mimeheader().

          Der Mailbody muss nicht unbedingt kodiert werden, muss aber mit einem passenden Header versehen werden.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
  4. Tach!

    Logfiles und wie mail() funktioniert, wurde ja schon angesprochen. Hier noch zwei Sicherheitshinweise.

    mail('office@test.com',
         'Nachricht von '.$_POST['vorname'].' '.$_POST['nachname'],
         stripslashes($_POST['message']), $extra)
    
    mail($_POST['email'],
         'Kopie Ihrer Nachricht ',
         stripslashes($_POST['message']), $extra)
    

    Die Funktion stripslashes() hat man früher verwendet, als es das Feature namens Magic Quotes noch gab. Das ist aber seit langem ausgestorben, oder du betreibst eine uralte PHP-Version.

    Wenn du die Eingabe $_POST['email'] nicht noch anderweitig prüfst, hast du beim zweiten mail() eine wunderbare Spam-Schleuder gebaut. Man kann nämlich eine Menge Adressen angeben, an die dann dein Mailserver je eine Nachricht schickt. Das ist nicht nur für alle Empfänger ärgerlich, sondern auch für dich und deinen Hoster, weil der Server auf Blacklisten landet.

    dedlfix.

    1. Die Funktion stripslashes() hat man früher verwendet, als es das Feature namens Magic Quotes noch gab. Das ist aber seit langem ausgestorben, oder du betreibst eine uralte PHP-Version.

      Ich habe tatsächlich eine uralte PHP-Version, nämlich 5.6. Der Grund ist, dass ich fürchte, dass andere Dinge nicht mehr funktionieren, wenn ich auf eine neuere Version umstelle. Kann man ein Upgrade auf eine neuere Version üblicherweise auch ohne Risiko rückgängig machen?

      Wenn du die Eingabe $_POST['email'] nicht noch anderweitig prüfst, hast du beim zweiten mail() eine wunderbare Spam-Schleuder gebaut. Man kann nämlich eine Menge Adressen angeben, an die dann dein Mailserver je eine Nachricht schickt. Das ist nicht nur für alle Empfänger ärgerlich, sondern auch für dich und deinen Hoster, weil der Server auf Blacklisten landet.

      Ich prüfe die Eingaben vorher und sammle sie in einer Vorschau-Ansicht. Die gesammelten Daten in meinem Beispiel-Script sind das Ergebnis dessen, was nach der Überprüfung und der generierten Vorschau durch manuelles Bestätigen weitergeschickt wird. Ist das ok so?

      dedlfix.

      1. Tach!

        Die Funktion stripslashes() hat man früher verwendet, als es das Feature namens Magic Quotes noch gab. Das ist aber seit langem ausgestorben, oder du betreibst eine uralte PHP-Version.

        Ich habe tatsächlich eine uralte PHP-Version, nämlich 5.6.

        Die ist zwar alt, aber selbst da gabs die Magic Quotes schon eine Weile nicht mehr.

        Der Grund ist, dass ich fürchte, dass andere Dinge nicht mehr funktionieren, wenn ich auf eine neuere Version umstelle. Kann man ein Upgrade auf eine neuere Version üblicherweise auch ohne Risiko rückgängig machen?

        Das kommt ganz drauf an, wie das PHP installiert wird. Es gibt auch Parallel-Installationen, dann wäre es gar kein Problem.

        Wenn du die Eingabe $_POST['email'] nicht noch anderweitig prüfst, hast du beim zweiten mail() eine wunderbare Spam-Schleuder gebaut. Man kann nämlich eine Menge Adressen angeben, an die dann dein Mailserver je eine Nachricht schickt. Das ist nicht nur für alle Empfänger ärgerlich, sondern auch für dich und deinen Hoster, weil der Server auf Blacklisten landet.

        Ich prüfe die Eingaben vorher und sammle sie in einer Vorschau-Ansicht. Die gesammelten Daten in meinem Beispiel-Script sind das Ergebnis dessen, was nach der Überprüfung und der generierten Vorschau durch manuelles Bestätigen weitergeschickt wird. Ist das ok so?

        Wenn du die Vorschau machst, dann ja. Wenn es der Anwender ist, dann nicht. Spammer bestätigen in der Regel sehr gern ihren Müll.

        dedlfix.

    2. mail($_POST['email'],
           'Kopie Ihrer Nachricht ',
           stripslashes($_POST['message']), $extra)
      

      Der Grundregelverstoß ist schon, dass der Benutzer Empfängeradresse und Inhalt eines der beiden Mails bestimmt.

      Lösung:

      Das Bestätigungsmail keineswegs versenden, sondern nur auf der Webseite anzeigen.

      1. aha, das wusste ich nicht. d.h. ich könnte dem Benutzer eine allgemeine Mail schicken, dass ich seine Mail erhalten habe, aber nicht mit dem von ihm eingegebenen Inhalt?

        1. Hallo,

          aha, das wusste ich nicht. d.h. ich könnte dem Benutzer eine allgemeine Mail schicken, dass ich seine Mail erhalten habe, aber nicht mit dem von ihm eingegebenen Inhalt?

          das ist nicht der Punkt. Das Problem ist, dass du eine e-Mail verschickst, bei der ein völlig Fremder sowohl die Empfängeradresse als auch den Inhalt frei eingeben kann. Okay, du nimmst an, dass der Besucher seine eigene Mailadresse angibt - was aber, wenn er eine (oder viele) völlig fremde angibt? Dann verschickt dein Server ungefragt SPAM an Fremde.

          Und das möchte man auf gar keinen Fall.

          Deswegen: Keine Mail an Adressen, die nicht zweifelsfrei verifiziert sind.

          So long,
           Martin

          --
          Computer müssen weiblich sein: Eigensinnig, schwer zu durchschauen, immer für Überraschungen gut - aber man möchte sie nicht missen.
          1. Deswegen: Keine Mail an Adressen, die nicht zweifelsfrei verifiziert sind.

            In diesem Fall gilt das. Aber bei einem Double-Opt-In ist der Versand an nicht "nicht zweifelsfrei verifizierte Adressen" (wenn nicht mit Werbung verbunden) erlaubt.

            1. Moin,

              Deswegen: Keine Mail an Adressen, die nicht zweifelsfrei verifiziert sind.

              In diesem Fall gilt das. Aber bei einem Double-Opt-In ist der Versand an nicht "nicht zweifelsfrei verifizierte Adressen" (wenn nicht mit Werbung verbunden) erlaubt.

              doppelte Verneinung will gelernt sein. ;-)

              Aber in deinem Sinne interpretiert, ist deine Aussage ja kein Widerspruch zu meiner: Nach einem Double Opt-In ist die Mailadresse ja verifiziert. Das heißt nicht, dass ich dann weiß, zu welcher Person sie gehört - aber auf jeden Fall, dass sie im Zugriffsbereich der Person liegt, die da gerade anfragt, und nicht jemand ganz anderem gehört.

              Ciao,
               Martin

              --
              Computer müssen weiblich sein: Eigensinnig, schwer zu durchschauen, immer für Überraschungen gut - aber man möchte sie nicht missen.
              1. Hello,

                [•••] aber vor dem Opt-In eben noch nicht.

                Allerdings liegt die Eingabemöglichkeit für die Empfängeradresse dann hinter einem Account-Create, also hoffentlich der Abfrage plausibler Daten. Das schaffen bei einstufigen Account-Create-Verfahren einige Bots zwar auch schon, diese Hürde zu überwinden, aber doch sehr selten.

                Außerdem sollte man als Zieladresse immer nur eine einzige zulassen. Die meisten Webserver würden ja auch mehrere, durch Komma getrennt in einer Zeile, annehmen.

                Glück Auf
                Tom vom Berg

                --
                Es gibt nichts Gutes, außer man tut es!
                Das Leben selbst ist der Sinn.