Die PHP Funktion asort kann auch mit UTF-8 Werten genutzt werden. Voraussetzung ist allerdings, dass in einem Array mit Textwerten, das richtige locale gesetzt ist. Zudem muss die Konstante SORT_LOCALE_STRING bei asort benutzt werden. Nun tritt dennoch ein Problem auf: Wenn die Textwerte UTF-8 kodiert sind, werden die Ergebnisse trotzdem single-byte sortiert, also z.B. ‘Ä’ aber auch ‘Ö’ kommen gleich nach dem ‘A’ weil diese Zeichen in UTF-8 mit zwei Zeichen kodiert sind wobei ‘Ã’ das erste davon ist.
Um dies zu lösen sind zwei Wege möglich:
1. Weg: Locale mit Charset setzten
setlocale(LC_COLLATE, 'de_DE.UTF8', 'de.UTF8', 'DEU.UTF8', 'German_Germany.UTF8', 'German.UTF8'
'de_DE.UTF-8', 'de.UTF-8', 'DEU.UTF-8', 'German_Germany.UTF-8', 'German.UTF-8'); Diese Methode ist systemabhängig und birgt ein gewisses Risiko, da in manchen Systemen die Locale nicht richtig gesetzt sind. Windows (als Server) unterstützt z.B. UTF-8 als Zeichenkodierung meist nicht (Windows benutzt WinCP, z.B. 1252).
2. Weg: Klasse ”Collate” benutzten
$coll = collator_create('de_DE');Diese Lösung ist erst ab PHP 5.3.0 möglich und erfordert, dass die PHP-Extension php_intl installiert ist. Dies kann dann wie folgt abgefragt resp. benutzt werden:
$oldLocale = setlocale(LC_COLLATE, '0');
if (preg_match('/\\.utf-?8\\b/i', $oldLocale)) {
// Alles richtig gesetzt
asort($arrayToSort, SORT_LOCALE_STRING);
}
elseif (version_compare(PHP_VERSION, '5.3.0') < 1 && function_exists('collator_create')) {
// Wir benutzten die Collator Klasse
$coll = collator_create($oldLocale);
collator_asort($coll, $arrayToSort, Collator::SORT_STRING);
}
else {
// Wir versuchen locale mit Zeichenkodierung setzten
$lang = preg_replace('/(?:\\.|\\@).*$/', '', $oldLocale);
foreach (array('.UTF-8', '.utf-8', '.UTF8', '.utf8', '') as $enc)
$locale[] = $lang . $enc;
$newLocale = setlocale(LC_COLLATE, $locale);
if (preg_match('/\\.utf-?8\\b/i', $newLocale)) {
asort($arrayToSort, SORT_LOCALE_STRING);
setlocale(LC_COLLATE, $oldLocale);
}
else {
// An diesem System funktioniert es nicht :(
// Es bleibt nichts Anderes übrig als User-function zu schreiben
// und 'usort'/'uasort' zu benutzen
}
}
Keine Kommentare:
Kommentar veröffentlichen