Horst Scheibenhofer: mail subject mit Umlauten

Hallo!

Wie schaffe ich es, dass ich beim Versenden einer Mail mit mail(..) ein Subject setzen kann, dass Umlaute enthält?

Mein Code:
$subject = utf8_decode($subject);
$content_type = "Content-Type: text/html\n";
$encoding = "Content-Transfer-Encoding: 8bit\n";

$header = "MIME-Version: 1.0\n"
              .$from
              .$reply
              .$cc
              .$bcc
              .$mail_header
              .$content_type
              .$encoding;
return mail($to,$subject,$body,$header);

Wenn jetzt zb ein Ö im Subject ist, wird stattdessen ein ? dargestellt.
Vorher noch ein $subject=htmlentities($subject) nützt auch nix. dann wird im Subject Ö angezeigt. (Habs jetzt nur mit dem Mozilla Mail Client probiert.

Hab mir jetzt mal den Quelltext eines Mails mit Umlaut im Subject angesehen. Aus "NÖ Umlaut" wird ein "=?ISO-8859-1?Q?N=D6_Umlaute?="
Wie kann man diesen String erzeugen?

Irgendwelche Lösungsvorschläge?

Danke
  Horst

  1. Hallo Horst,

    Hast Du mal probiert \xFC (Hexwert von ü) zu schreiben.

    Gruß,

    Dieter

    1. Hallo Horst,
      Hast Du mal probiert \xFC (Hexwert von ü) zu schreiben.

      Nö, werd ich heut Abend mal versuchen.

      Danke!
         Horst

  2. Hallo,

    Hab mir jetzt mal den Quelltext eines Mails mit Umlaut im Subject angesehen. Aus "NÖ Umlaut" wird ein "=?ISO-8859-1?Q?N=D6_Umlaute?="
    Wie kann man diesen String erzeugen?

    Da bist du auf dem richtigen Weg. Alle 8-Bit-Zeichen müssen auf diese Weise maskiert werden. D6 ist der hexadezimale Wert für »Ö« im Zeichensatz ISO-8859-1. Das ganze wird in =?ISO-8859-1?Q? ... ?= eingeschlossen. Das geht z.B. so:

    $str = preg_replace('~([\xA0-\xFF])~e', '"=" . strtoupper(dechex(ord("$1")))', $str);
    $str = '=?ISO-8859-1?Q?' . $str . '?=';

    Jemand wird dir auch sicher aus dem Kopf sagen können, in welchem RFC das geregelt ist.

    Mathias

    1. $str = preg_replace('~([\xA0-\xFF])~e', '"=" . strtoupper(dechex(ord("$1")))', $str);
      $str = '=?ISO-8859-1?Q?' . $str . '?=';

      Danke! Das wars!

      mfg
        Horst

    2. Hallo Mathias,

      $str = preg_replace('~([\xA0-\xFF])~e', '"=" . strtoupper(dechex(ord("$1")))', $str);

      Ich hatte schon immer Schwierigkeiten, den Modifier e zu verstehen, koenntest Du mir da bitte etwas nachhelfen? Auf http://de3.php.net/manual/en/reference.pcre.pattern.modifiers.php habe ich schon nachgesehen, aber irgendwie faellt mir der Groschen nicht.
      Mir ist soweit klar, dass alle Umlaute usw. durch Ihren Hexwert ersetzt werden sollen, was das strtoupper usw. macht, ist auch klar.
      Vielleicht kannst Du das ganze preg_replace() mal in Umgangssprache uebersetzen.

      Gruß,

      Dieter

      1. Hallo,

        $str = preg_replace('~([\xA0-\xFF])~e', '"=" . strtoupper(dechex(ord("$1")))', $str);

        Der e-Modifier bedeutet »führe den zweiten preg_replace-Parameter bei jedem Vorkommen des Patterns als PHP-Ausdruck aus und ersetze das Vorkommen durch das Ergebnis des Ausdrucks«.

        Das Muster [\xA0-\xFF] trifft auf alle Bytes mit den Werten 160 bis 255 zu. Das sind alle Nicht-ASCII-Zeichen in der Kodierung ISO-8859-1. (Achtung, die zusätzlichen Zeichen zwischen 128 und 160 in Windows-1252 werden nicht berücksichtigt! Wenn Formulardaten verarbeitet werden, muss dafür gesorgt werden, dass der Browser Eurozeichen usw. nicht Windows-1252-kodiert sendet.)

        Immer wenn nun ein Zeichen mit einem solchen Bytewert gefunden wird, wird der String im zweiten preg_replace-Parameter als PHP-Ausdruck ausgewertet. Zuerst werden die Backreferences durch die jeweiligen Treffer ersetzt, dann wird der Ausdruck ausgeführt (vergleichbar mit eval()) und der Rückgabewert anstelle des gefundenen Zeichens eingesetzt.

        Zur Veranschaulichung:
        echo(preg_replace('~[\xA0-\xFF]~e', 'print "$0, "', 'üöä'));
        print gibt immer einen Integer-Wert zurück, nämlich 1. Diese Zeile gibt also aus ü, ö, ä, 111. $0 wird durch den gesamten Treffer ersetzt, dann wird »print 'ü, '« usw. ausgeführt. Das Ergebnis dieses Ausdrucks ist der Ersatz für »ü« usw.

        In »"=" . strtoupper(dechex(ord("$1")))« wird zunächst der Bytewert des gefundenen Zeichens in Erfahrung gebracht (z.B. ord('ü') ergibt 252). Dieser Bytewert - der immer dann, wenn ein String erwartet wird, automatisch in einen String mit dezimaler Schreibweise umgewandelt wird - wird in eine hexadezimale Zahl umgewandelt (z.B. ord(252) == 'fc'). Die Buchstaben dieses Hex-Wertes werden zu Großbuchstaben (z.B. 'FC') und vorne an den String wird »=« gehangen. Heraus kommt z.B. '=FC', das anstelle von »ü« eingefügt wird.

        Mathias

        1. Hallo Mathias,

          Vielen Dank fuer die ausfuehrliche Antwort, jetzt ist mir das klar. Ich werde mal ein bischen damit experimentieren, um etwas Routine zu erlangen.

          Gruß,

          Dieter