utf-8 vs. iso-8859-1

Hallo,

folgendes Problem: Ich habe eine Anwendung, die in utf-8 läuft. Zu
dieser Anwendung gibt es externe Schnittstellen, die in iso-8859-1
laufen und die ich nicht beeinflussen kann.

In meiner Anwendung werden Daten in einem Formular geschrieben und in
MySQL-Db abgespeichert. Jetzt meine Frage: Ist es möglich die
Formular-Daten so zu filtern, dass ausschließlich die Zeichen erlaubt
werden, die ihre Entsprechung in iso-8859-1 haben? Z.B. sollte im
Formular ein kyrillisches Zeichen auftauchen, kommt eine Fehlermeldung;
werden aber die deutschen Umlaute eingegeben soll es in der Datenbank
abgespeichert werden.

Hat jemand eine Idee, wie man es prüfen kann?

Gruß

Monika
Renata Nowak [ Di, 20 November 2007 09:13 ] [ ID #1875209 ]

Re: utf-8 vs. iso-8859-1

Monika Nowak schrieb:
> Hallo,
>
> Z.B. sollte im
> Formular ein kyrillisches Zeichen auftauchen, kommt eine Fehlermeldung;
> werden aber die deutschen Umlaute eingegeben soll es in der Datenbank
> abgespeichert werden.
>
> Hat jemand eine Idee, wie man es prüfen kann?

Du könntest ein utf8_encode mit anschließendem utf8_decode machen und
das Ergebnis miteinander vergleichen. Gibt es Unterschiede zwischen
beiden Strings, so wurden Zeichen verwendet, die außerhalb von 8859-1
liegen.

Michael
Michael Vogel [ Di, 20 November 2007 11:12 ] [ ID #1875210 ]

Re: utf-8 vs. iso-8859-1

Monika Nowak schrieb:

> folgendes Problem: Ich habe eine Anwendung, die in utf-8 läuft. Zu
> dieser Anwendung gibt es externe Schnittstellen, die in iso-8859-1
> laufen und die ich nicht beeinflussen kann.

> In meiner Anwendung werden Daten in einem Formular geschrieben und in
> MySQL-Db abgespeichert. Jetzt meine Frage: Ist es möglich die
> Formular-Daten so zu filtern, dass ausschließlich die Zeichen erlaubt
> werden, die ihre Entsprechung in iso-8859-1 haben? Z.B. sollte im
> Formular ein kyrillisches Zeichen auftauchen, kommt eine Fehlermeldung;
> werden aber die deutschen Umlaute eingegeben soll es in der Datenbank
> abgespeichert werden.

> Hat jemand eine Idee, wie man es prüfen kann?

Neben der Quick'n'Dirty-Methode, die Michael schon genannt hat, gibt es
die Möglichkeit, die Eingabe Byte für Byte zu analysieren. Ich habe dazu
eine Funktion gebaut, die du direkt einsetzen kannst (siehe unten).

Erklär-Bär: ISO-8859-1 ist durch den Unicode-Bereich 0x0000-0x00FF
vollständig abgedeckt. Genauer gesagt enthält 0x0000-0x007F alle
ASCII-Zeichen und 0x0080-0x00FF den Rest.

UTF-8 ist eine (nicht die einzige) mögliche Kodierung für Unicode, mit
der sich alle Unicode-Zeichen abbilden lassen. Jeder Unicode-Bereich
wird entsprechend kodiert auf 1 bis 4 Bytes abgebildet.

Vgl. <http://de.wikipedia.org/wiki/UTF-8>

Der für deine Zwecke relevante Unicode-Bereich 0000-00FF wird in UTF-8
zum Teil auf 1 Byte abgebildet (alle ASCII-Zeichen) und zum Teil auf
max. 2 Byte (alle anderen Zeichen aus ISO-8859-1). In UTF-8 entspricht
ISO-8859-1 also den Bereichen 0x00 bis 0x7F (Single-Byte) und 0xC280 bis
0xC3BF (2-Byte).

In der Funktion teste ich Byte für Byte. Befindet sich das Byte im
Bereich der ASCII-Zeichen, dann ist es erlaubt. Hat das Byte den Wert
0xC2 oder 0xC3, dann könnte es sich um das Start-Byte eines 2-Byte-Chars
handeln. Also wird das nächste Zeichen gelesen und der 2-Byte-Char wird
erzeugt. Wenn das Zeichen dann zwischen 0xC280 und 0xC3BF liegt ist es
in ISO-8859-1 dargestellbar, ansonsten nicht.

/**
* Checks the given UTF-8 string for non ISO-8859-1 characters.
*
* [at] param string $chars The UTF-8 string to check
* [at] return int -1 if the string is valid, the byte-code of the rejected
* char otherwise
*/
function checkLatin1($chars) {
for($i = 0, $n = strlen($chars); $i < $n; $i++) {
$c = ord($chars[$i]);

// 0000-007F (ASCII, single-byte)
if($c >= 0x00 && $c <= 0x7F) {
continue;
}

// C200-C3FF
if($c >= 0xC2 && $c <= 0xC3 && $i < $n - 1) {
$c = ($c << 8) + ord($chars[++$i]);

// C280-C3BF
if($c >= 0xC280 && $c <= 0xC3BF) {
continue;
}
}

return $c;
}

return -1;
}

if(($c = checkLatin1($chars)) > -1) {
echo "Illegal character found: ", dechex($c), "\n";
}
else {
echo "It's save to convert to ISO-8859-1:\n";
echo utf8_decode($chars);
}

So kannst du dann analog auch andere Zeichensätze testen, was mit
utf8_decode() nicht möglich ist. Man muss sich dann halt nur genau
informieren, in welchen Bereichen die Zeichen liegen.

<http://www.utf8-zeichentabelle.de/> ist dafür ziemlich hilfreich. Ob es


HTH

--
"Faulheit ist die Wurzel allen Fortschritts!"
(Inhalt eines Knallbonbons, 2002)
dafox [ Di, 20 November 2007 22:14 ] [ ID #1875215 ]

Re: utf-8 vs. iso-8859-1

Vielen Dank! Das hat mir schon sehr geholfen!

Gruß
Monika
Renata Nowak [ Mi, 21 November 2007 14:42 ] [ ID #1876040 ]

Re: utf-8 vs. iso-8859-1

Ein besonderer Dank an Dich Thomas! :) Vor allem für die ausführliche
Erklärung. Die Methode, die Du vorgestellt hast, kann ich wirklich sehr
gut gebrauchen :)

Gruß

Monika
Renata Nowak [ Do, 22 November 2007 09:03 ] [ ID #1876778 ]
PHP » de.comp.lang.php.misc » utf-8 vs. iso-8859-1

Vorheriges Thema: zip.so extension läßt sich nicht laden beim Provider
Nächstes Thema: PHP als Mini-HTTP-Server