В конечном итоге эту проблему невозможно решить простым способом без использования перекодированных строк (UTF-8 → Windows-1252 или ISO-8859-1), как это было предложено ΤΖΩΤΖ, из-за очевидной ошибки PHP, обнаруженной Хаппи.
Чтобы подвести итог проблемы, я создал следующий фрагмент кода, который ясно демонстрирует, что проблема заключается в функции strcoll () при использовании кодовой страницы 65001 Windows-UTF-8.
function traceStrColl($a, $b) {
$outValue=strcoll($a, $b);
echo "$a $b $outValue\r\n";
return $outValue;
}
$locale=(defined('PHP_OS') && stristr(PHP_OS, 'win')) ? 'German_Germany.65001' : 'de_DE.utf8';
$string="ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜabcdefghijklmnopqrstuvwxyzäöüß";
$array=array();
for ($i=0; $i<mb_strlen($string, 'UTF-8'); $i++) {
$array[]=mb_substr($string, $i, 1, 'UTF-8');
}
$oldLocale=setlocale(LC_COLLATE, "0");
var_dump(setlocale(LC_COLLATE, $locale));
usort($array, 'traceStrColl');
setlocale(LC_COLLATE, $oldLocale);
var_dump($array);
Результат:
string(20) "German_Germany.65001"
a B 2147483647
[...]
array(59) {
[0]=>
string(1) "c"
[1]=>
string(1) "B"
[2]=>
string(1) "s"
[3]=>
string(1) "C"
[4]=>
string(1) "k"
[5]=>
string(1) "D"
[6]=>
string(2) "ä"
[7]=>
string(1) "E"
[8]=>
string(1) "g"
[...]
Тот же фрагмент работает на компьютере с Linux без каких-либо проблем, получая следующий вывод:
string(10) "de_DE.utf8"
a B -1
[...]
array(59) {
[0]=>
string(1) "a"
[1]=>
string(1) "A"
[2]=>
string(2) "ä"
[3]=>
string(2) "Ä"
[4]=>
string(1) "b"
[5]=>
string(1) "B"
[6]=>
string(1) "c"
[7]=>
string(1) "C"
[...]
Фрагмент также работает при использовании строк в кодировке Windows-1252 (ISO-8859-1) (конечно, тогда необходимо изменить кодировки mb_ * и локаль).
Я отправил отчет об ошибке на bugs.php.net : Ошибка # 46165 strcoll () не работает со строками UTF-8 в Windows . Если у вас возникла та же проблема, вы можете оставить свой отзыв команде PHP на странице отчета об ошибках (две другие, вероятно, связанные, ошибки были классифицированы как поддельные - я не думаю, что эта ошибка это фальшивка ; -).
Спасибо всем вам.