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