mb_send_mail will manchmal nicht senden
Kalle_B
- php
Hallöle,
ein seltsames Phänomen. Ein Besucher kann eine Webseite empfehlen und gibt dafür die E-Mail des Empfängers ein.
Diese E-Mail klappt: osmer.khATgmx.de
aber diese nicht: osmer.khATosmer.de
Klappen heißt, mb_send_mail gibt TRUE zurück, sonst FALSE. Mehr Infos gibt's leider nicht - oder doch?
Das AT ist natürlich ein @. Bevor die Mails gesendet werden, wird $_POST mit Slashes versehen und dann mit der Funktion
// =================================
function quote2html ( $string ) {
// =================================
// 2009-09-17 ERSETZT EINFACHES UND DOPPELTES ANFUEHRUNGSZEICHEN DURCH HTML-SPECIAL
$string = stripslashes($string); // kann von GET, POST, COOKIE kommen
$string = htmlspecialchars($string);
$string = str_replace( "'", "'", $string ); // kann aus DB kommen
$string = str_replace( '"', """, $string ); // kann aus DB kommen
return $string;
}
wieder ent-slasht. Aber das kann ja wohl den Unterschied nicht erklären.
Hier der PHP-Schnippsel um's Mailsenden herum:
mb_language ( 'uni' ); // UTF-8
if ( $i == 1 )
{
// MAIL AN SENDER/EMPFAENGER
if ( $arr_in['email_s'] ) mb_send_mail( $arr_in['email_s'], $mail_subject, $mail_body, $mail_header );
$_hmail_sent = mb_send_mail( $arr_in['email_e'], $mail_subject, $mail_body, $mail_header );
$_h00 =( $_h00 || $_hmail_sent );
$_femail_gesendet =(!$_hmail_sent );
if ( $_femail_gesendet ) echo $arr_in['email_e']."<br>";
$_fmail =( $_fmail || $_femail_gesendet );
}
else if ( $i == 2 )
{
// MAIL AN VERANSTALTER/WEBMASTER
if ( $row_trm['vtr_email'] ) mb_send_mail( $row_trm['vtr_email'], $mail_subject, $mail_body, $mail_header );
mb_send_mail( "osmer.kh@gmx.de", $mail_subject, $mail_body, $mail_header );
}
Woran könnte es liegen?
Muss die Mail-Adresse innerhalb von mb_send_mail bei UTF8 mit mb_encode_mimeheader behandelt werden? Das ist doch wohl nur für den Mail-Header angesagt?
LG Kalle
Hello,
ein seltsames Phänomen. Ein Besucher kann eine Webseite empfehlen und gibt dafür die E-Mail des Empfängers ein.
Diese E-Mail klappt: osmer.khATgmx.de
aber diese nicht: osmer.khATosmer.de
Du meinst, die Empfanger-Mail-Server nehmen die eMails nicht an?
Hast Du Einblick in die Protokolle der betroffenen Mailserver?
Dann sende bitte mal die entsprechnden Zeilen.
Die sind sowohl beim absendenden SMTP-Server, als auch beim empfangenen SMTP-Server interessant.
$string = htmlspecialchars($string);
$string = str_replace( "'", "'", $string ); // kann aus DB kommen
$string = str_replace( '"', """, $string ); // kann aus DB kommen
Warum das?
$string = htmlspecialchars($string, ENT_QUOTES);
leistet das bereits. Du solltest ggf. aber die gewählte Codierung noch mit angeben
http://de.php.net/manual/en/function.htmlspecialchars.php
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
$string = htmlspecialchars($string, ENT_QUOTES);
leistet das bereits. Du solltest ggf. aber die gewählte Codierung noch mit angeben
http://de.php.net/manual/en/function.htmlspecialchars.php
Die Kodierungsangabe benötigt man weder für ISO-8859-1 noch für UTF-8. Alle von htmlspecialchars() zu lesenden und schreibenden Zeichen liegen im ASCII-Bereich und werden auch ohne charset-Angabe korrekt behandelt.
Lo!
Hello,
$string = htmlspecialchars($string, ENT_QUOTES);
leistet das bereits. Du solltest ggf. aber die gewählte Codierung noch mit angeben
http://de.php.net/manual/en/function.htmlspecialchars.phpDie Kodierungsangabe benötigt man weder für ISO-8859-1 noch für UTF-8. Alle von htmlspecialchars() zu lesenden und schreibenden Zeichen liegen im ASCII-Bereich und werden auch ohne charset-Angabe korrekt behandelt.
Die bezieht sich also nur auf das Zielsystem? Ich war der Meinung, dass das für das Quellsystem gilt.
*Leichte Verwirrung*
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Die Kodierungsangabe benötigt man weder für ISO-8859-1 noch für UTF-8. Alle von htmlspecialchars() zu lesenden und schreibenden Zeichen liegen im ASCII-Bereich und werden auch ohne charset-Angabe korrekt behandelt.
Die bezieht sich also nur auf das Zielsystem? Ich war der Meinung, dass das für das Quellsystem gilt. *Leichte Verwirrung*
Ich meinte, dass für die ISO-8859-Familie (alle, nicht nur -1) und UTF-8 (und auch Windows-1252) die auf der Eingangsseite berücksichtigten und die für die Ausgabe der Substitute verwendeten Zeichen alle unterhalb 0x80 liegen, die gleichen Bytewerte haben und damit unverwechselbar sind, so dass es egal ist, ob man charset mit ISO-8859-1 oder UTF-8 (oder cp1252) füttert oder ganz weglässt.
Lo!
Hello,
Hi!
Die Kodierungsangabe benötigt man weder für ISO-8859-1 noch für UTF-8. Alle von htmlspecialchars() zu lesenden und schreibenden Zeichen liegen im ASCII-Bereich und werden auch ohne charset-Angabe korrekt behandelt.
Die bezieht sich also nur auf das Zielsystem? Ich war der Meinung, dass das für das Quellsystem gilt. *Leichte Verwirrung*
Ich meinte, dass für die ISO-8859-Familie (alle, nicht nur -1) und UTF-8 (und auch Windows-1252) die auf der Eingangsseite berücksichtigten und die für die Ausgabe der Substitute verwendeten Zeichen alle unterhalb 0x80 liegen, die gleichen Bytewerte haben und damit unverwechselbar sind, so dass es egal ist, ob man charset mit ISO-8859-1 oder UTF-8 (oder cp1252) füttert oder ganz weglässt.
Damit muss ich mich doch nochmal intensiver befassen. So ist mir das zu schwammig.
Dein Hinweis hat mich jetzt nochmal darauf gestoßen...
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Damit muss ich mich doch nochmal intensiver befassen. So ist mir das zu schwammig.
Dein Hinweis hat mich jetzt nochmal darauf gestoßen...
htmlspecialchars() interessiert sich für die Zeichen: &"'<>
Für die Ausgabe verwendet es: &;#039aglmopqtu
All das sind Zeichen aus dem ASCII-Bereich 0x00..0x7f, der bei ISO-8859 und UTF-8 exakt gleich ist. Es spielt also überhaupt keine Geige, welches charset man nun angibt. Es wird stets aus dem gleichen Input das gleiche Output erzeugt.
Anders ist die Sachlage bei htmlentities(), aber das benötigt man in aller Regel nicht, beziehungsweise ist es besser, seine Anwendung so zu bereinigen, dass man es nicht benötigt.
Die charset-Angabe wird lediglich für einige der asiatischen Kodierungen benötigt, denn da gibt es Kombinationen von Bytes, die zwar die "ASCII-Bytes" enthalten, aber für ein Nicht-ASCII-Zeichen stehen. Ein byteweises Bearbeiten führt also zur Zerstörung der Kombinationen.
Das gleiche Prinzip gilt für mysql_set_charset() versus SET NAMES im Zusammenhang mit mysql_real_escape_string(). Handelt man die Verbindungskodierung mit mysql_set_charset() aus, wird diese Kodierung von mysql_real_escape_string() berücksichtigt, bei SET NAMES hingegen nicht. Auch hier hat man wieder Probleme mit einigen asiatischen Kodierungen, nicht jedoch mit ISO-8859 oder UTF-8, weil ebenfalls alle interessierenden Zeichen nur im Bereich 0x00..0x7f angesiedelt sind.
Lo!
Hi!
... Auch hier hat man wieder Probleme mit einigen asiatischen Kodierungen, nicht jedoch mit ISO-8859 oder UTF-8, weil ebenfalls alle interessierenden Zeichen nur im Bereich 0x00..0x7f angesiedelt sind.
Verständnisfrage: Enthält UTF-8 die asiatischen Kodierungen? Wieso zeigst du einen Widerspruch auf?
Ich denke, mit UTF-8 bin ich für alle Kodierungen gewappnet?
Und - ist es richtig, dass chinesisch den umfangreichsten Zeichensatz hat? Also wenn Programme und Datenbank mit chinesisch umgehen können, klappen auch die anderen?
Kalle
Hi!
... Auch hier hat man wieder Probleme mit einigen asiatischen Kodierungen, nicht jedoch mit ISO-8859 oder UTF-8, weil ebenfalls alle interessierenden Zeichen nur im Bereich 0x00..0x7f angesiedelt sind.
Verständnisfrage: Enthält UTF-8 die asiatischen Kodierungen?
UTF-8 enthält keine, sondern ist eine Kodierung. Eine für den Zeichensatz Unicode. Unicode listet eine Menge Zeichen auf, unter anderem asiatische. Es gibt auch noch einige andere Zeichensätze und Kodierungen. Der Unterschied zwischen Zeichensatz und Kodierung ist oft nicht deutlich sichtbar, bei Unicode jedoch ist er es. Unicode ist ein Zeichensatz und damit eine sozusagen theoretische Liste. Jedes Zeichen in dieser Liste wird durch einen Codepoint repräsentiert. Ein Codepoint hat eine Nummer, ist aber ansonsten auch ein eher theoretisches Gebilde. Ins Praktische kommt man durch eine Kodierung. Die UTF-Kodierungen sind eine Vorschrift, wie aus den Codepoints eine konkrete Bytefolge wird, mit der das Zeichen nun im Speicher oder einer Datei abgebildet werden kann. Im Gegensatz zu den anderen Zeichensätzen gibt es mit UTF-8/16/32/... mehrere Arten, um vom einem bestimmten Codepoint zu einer konkreten Bytefolge zu kommen. Unicode ist also ein Zeichensatz, der mit den UTFs mehrere Kodierungen kennt. Bei den anderen Zeichensätze war beispielweise aufgrund ihrer Beschränktheit die Notwendigkeit des Codepoint-Zwischenschritts nicht notwendig.
Jedoch ergab sich die Notwendigkeit, im asiatischen Raum mehr als 256 Zeichen abbilden zu müssen, ohne dass man den grundlegenden Ansatz von Unicode gegangen ist, gehen konnte oder wollte. Jedenfalls musste man mehrere Bytes verwenden, um ein Zeichen darstellen zu können.
Wieso zeigst du einen Widerspruch auf?
Es ist kein Widerspruch sondern liegt an der Art, wie die verschiedenen Kodierungen die Zeichen zu Bytes machen. UTF-8 verwendet die Bytes 00..7F für die 127 ASCII-Zeichen - jedes Zeichen hat damit sein eigenes Byte. Die Codepoint oberhalb von 127 werden mit mehreren Bytes dargestellt, die aber ausschließlich im Bereich 80..FF liegen. Wie bereits gesagt, liegen alle von htmlspecialchars() behandelten Zeichen im Bereich 00..7F und sind damit eineindeutig zu Bytes zugeordnet. Anders sieht es bei einigen asiatischen Kodierungen aus, die verwenden die Bytes 00..7F teilweise mehrfach. Beispielsweise steht das Byte 26h in Kombination mit anderen Bytes nicht für das Zeichen &. Das Byte 26h ist also nicht eineindeutig dem & zugeordnet. Es muss mal als solches behandelt werden und mal darf es das nicht, um die Kombination mit den anderen Bytes und damit das repräsentierte Zeichen nicht zu zerstören. In dem Fall ist es wichtig, dass der Rechner weiß, dass XX26 nicht zu XX26616D703B (x&) umgeschrieben werden darf. Deswegen muss für diese Kodierungen mit mehrdeutiger Verwendung der ASCII-Bytes einerseits htmlspecialchars() und htmlentities() gesagt bekommen, gemäß welcher Zeichenkodierung es die ankommende Bytefolge zu interpretieren hat. Andererseits muss auch mysql_real_escape_string() die zu verwendende Kodierung kennen, weswegen in dem Fall kein SET NAMES geht, sondern nur mysql(i)_set_charset(), denn letzteres beeinflusst auch die Client-API und nicht nur den MySQL-Server.
Ich denke, mit UTF-8 bin ich für alle Kodierungen gewappnet?
Du solltest dir ein grundlegendes Verständnis über die Begriffe aneignen.
Und - ist es richtig, dass chinesisch den umfangreichsten Zeichensatz hat? Also wenn Programme und Datenbank mit chinesisch umgehen können, klappen auch die anderen?
Beide Fragen sind mit einem Nein zu beantworten. Es ist zwar so, dass die Chinesen eine ganze Menge Zeichen erfunden haben. Allerdings haben die Japaner ebenfalls diese Zeichen übernommen und dazu noch weitere (einfachere) Zeichen erfunden. Somit dürften die Japaner mehr Zeichen kennen als die Chinesen. Andererseits gab es in der Volksrepublik China im vorigen Jahrhundert eine Bestrebung, die teilweise aus sehr vielen Strichen bestehenden Zeichen zu vereinfachen. Somit sind eine Menge chinesische Zeichen in der traditionellen und der vereinfachten Variante verfügbar. Die Japaner blieben bei ihrem Gemisch aus traditionellen chinesischen Zeichen und den eigenen. Taiwan, Hong-Kong und einige Übersee-Chinesenpopulationen behielten ebenfalls ihre traditionellen Zeichen bei. Somit dürften es also wieder die Chinesen insgesamt sein, die die meisten Zeichen haben. Und bis zur Einführung von Unicode hatten sie - notwendigerweise - auch die umfangreichsten Zeichensätze. Ja, Mehrzahl - denn davon gab es nicht nur einen sondern historisch bedingt einige (MySQL kennt 9 Asian Character Sets).
Das Nein zur zweiten Frage sollte nun auch klar sein. Da es mehrere chinesische Zeichensätze (und Kodierungen) gibt, kann man nicht automatisch von "Chinesisch" auf alle anderen schließen. Ebensowenig kann man von Unicode/UTF auf alle anderen schließen. Wenn ein Programm mit einer bestimmten Kodierung umgehen kann, "klappt" genau diese eine Kodierung. Für die anderen Kodierungen müssen jeweils deren Eigenarten berücksichtigt werden und demzufolge jeweils eine individuelle Unterstützung ins Programm eingebaut sein. Das gilt vor allem bei Stringverarbeitung. Um beispielsweise Wortgrenzen erkennen zu können, muss bekannt sein, welche Zeichen Wortgrenzen darstellen und wie diese im Bytestrom der jeweiligen Kodierung zu erkennen sind.
Lo!
Hello,
Du meinst, die Empfanger-Mail-Server nehmen die eMails nicht an?
Bis dahin kommt die Mail wohl kaum, denn
$_hmail_sent = mb_send_mail( $arr_in['email_e'], $mail_subject, $mail_body, $mail_header );
ist in Sekundenbruchteilen FALSE, da kann wohl kaum der Empfänger eine Rückmeldung gegeben haben.
Hast Du Einblick in die Protokolle der betroffenen Mailserver?
Dann sende bitte mal die entsprechnden Zeilen.
Wo versteckt sich das Protokoll im Debian-Linux? Schreibt mb_send_mail den Grund der Ablehnung da rein?
$string = htmlspecialchars($string, ENT_QUOTES);
Danke.
Lieben Gruß, Kalle
Hello,
Bis dahin kommt die Mail wohl kaum, denn
$_hmail_sent = mb_send_mail( $arr_in['email_e'], $mail_subject, $mail_body, $mail_header );
ist in Sekundenbruchteilen FALSE, da kann wohl kaum der Empfänger eine Rückmeldung gegeben haben.
Das ist wohl wahr, weil der Rückgabewert von mail() nur auf der Ausfürhbarkeit der Funktioon beruht und durchgereicht wird. Also liegt der Fehler im Ausgangs-Host.
Dann müsstest Du bitte die genauere Installation nochmal beschreiben. Liegen beide Mail-Accounts auf demselben Host, bzw. welche Mailserver sind für die Domains eingerichtet? Sind es überhaupt zwei Domains, von denen aus Du die Sendeversuche machen lässt?
Hast Du Einblick in die Protokolle der betroffenen Mailserver?
Dann sende bitte mal die entsprechnden Zeilen.Wo versteckt sich das Protokoll im Debian-Linux? Schreibt mb_send_mail den Grund der Ablehnung da rein?
Kommt auf den Mailserver an, der da läuft. I.d.R. ist es Exim oder Postfix.
Da musst Du einfach mal die Doku lesen der zuständigen Version.
bei mir sind es /var/log/mail.log und /var/log/mail.err, die von Interesse sind.
Kann aber auch je nach Version umgelinkt sein auf /var/log/mail/ oder /var/mail/log/
ist ein bisschen chaotisch.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
bei mir sind es /var/log/mail.log und /var/log/mail.err, die von Interesse sind.
Kann aber auch je nach Version umgelinkt sein auf /var/log/mail/ oder /var/mail/log/
var/mail/www-data 444.419 25.09. rw-rw----
----- Transcript of session follows -----
... while talking to [127.0.0.1]:
DATA
<<< 550 5.1.1 <osmer.kh°osmer.de.org>... User unknown
550 5.1.1 osmer.kh°osmer.de... User unknown
<<< 503 5.0.0 Need RCPT (recipient)
osmer.kh°osmer.de gibt es aber. °=@
LG Kalle