Der alte Mann und die Umlaute

Wer immer schon Probleme mit php, CSV-Dateien und Umlauten hatte, wird sich sicher über das Schweizer Messer für die Umlaute freuen. Vor kurzem stellte sich mir die Problematik, dass ich eine unter MacOS erstellte CSV-Datei in eine mysql Datenbank importieren musste. Damit die MacOS formatierte Datei überhaupt gelesen werden konnte, muss die php Option auto_detect_line_endings aktiviert sein, sonst kann die file()-Funktion die Datei gar nicht erst einlesen. Hat man diese Hürde genommen, stoßen einem als nächstes die Umlaute komisch auf. Um diesem Übel Herr zu werden, kann man sich zum einen mit der Funktion show_encoding() die aktuellen Einstellungen für die php encoding Optionen ansehen.

// Wenn diese Option aktiviert ist, prüft PHP die von den Funktionen
// fgets() und file() gelesenen Daten, um festzustellen, ob diese
// Unix-, MS-DOS- oder Macintosh-Zeilenenden verwenden.
ini_set("auto_detect_line_endings", true);

/******************************************************************************
 * 
 *****************************************************************************/
function show_encoding()
{
    print "iconv encodings\n";
    var_dump(iconv_get_encoding('all'));
    
    print "\n";
    print "mb_internal_encoding: " . mb_internal_encoding() . "\n";
    print "mb_detect_order: " . implode(", ", mb_detect_order()) . "\n";
}

/******************************************************************************
 * 
 *****************************************************************************/
function detect_encoding($string, $print = true)
{
    print "encoding detected: " . mb_detect_encoding($string, "auto") . "\n";

    foreach(mb_list_encodings() as $chr)
    {
        if ($print)
        {
            print mb_convert_encoding($string, 'UTF-8', $chr) .
            " : " . $chr . "\n";    
        }
        else
        {
            $encoding[$chr] = mb_convert_encoding($string, 'UTF-8', $chr);
        }
    }
    
    if (!$print && count($encoding) > 0)
    {
        return $encoding;
    }
    else
    {
        return true;
    }
}

So sieht die Ausgabe von show_encoding() aus.

iconv encodings
array(3) {
  ["input_encoding"]=>
  string(10) "ISO-8859-1"
  ["output_encoding"]=>
  string(10) "ISO-8859-1"
  ["internal_encoding"]=>
  string(10) "ISO-8859-1"
}

mb_internal_encoding: ISO-8859-1
mb_detect_order: ASCII, UTF-8
encoding detected: UTF-8

Mit der Funktion detect_encoding() kann man sich jetzt eine Zeile der CSV-Datei ausgeben lassen und dort wo die Zeichen richtig dargestellt werden, steht das zu verwendende Encoding dahinter.

Und so die Ausgabe von detect_encoding("äöüß").

äöü� : pass
äöüß : auto
äöü� : wchar
???? : byte2be
???? : byte2le
? : byte4be
? : byte4le
 : BASE64
 : UUENCODE
äöü� : HTML-ENTITIES
äöüß : Quoted-Printable
äöü� : 7bit
äöü� : 8bit
? : UCS-4
? : UCS-4BE
? : UCS-4LE
???? : UCS-2
???? : UCS-2BE
???? : UCS-2LE
? : UTF-32
? : UTF-32BE
? : UTF-32LE
???? : UTF-16
???? : UTF-16BE
???? : UTF-16LE
äöüß : UTF-8
???????? : UTF-7
???????? : UTF7-IMAP
äöü� : ASCII
???? : EUC-JP
??????? : SJIS
???? : eucJP-win
??????? : SJIS-win
??????? : CP932
???? : CP51932
???????? : JIS
???????? : ISO-2022-JP
???????? : ISO-2022-JP-MS
äöüß : Windows-1252
äöüß : Windows-1254
äöü� : ISO-8859-1
?¤?????? : ISO-8859-2
?¤?????? : ISO-8859-3
�� : ISO-8859-4
???????? : ISO-8859-5
?¤?????? : ISO-8859-6
?€?????? : ISO-8859-7
?¤?¶?¼?? : ISO-8859-8
äöü� : ISO-8859-9
��� : ISO-8859-10
?¤?¶?¼?? : ISO-8859-13
�ö�� : ISO-8859-14
ÀöÌ� : ISO-8859-15
äöü� : ISO-8859-16
???? : EUC-CN
???? : CP936
???????? : HZ
???? : EUC-TW
???? : BIG-5
???? : EUC-KR
???? : UHC
???????? : ISO-2022-KR
?¤?¶???? : Windows-1251
???????? : CP866
???????÷ : KOI8-R
???????÷ : KOI8-U
?)?????? : ArmSCII-8
?ñ?Â???ƒ : CP850
???????? : JIS-ms
???????? : CP50220
???????? : CP50220raw
???????? : CP50221
???????? : CP50222

Ein Gedanke zu “Der alte Mann und die Umlaute

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *