PHP: mb_strtoupper не работает

У меня проблема с UTF-8 и mb_strtoupper.

mb_internal_encoding('UTF-8'); $guesstitlestring='Le Courrier de Sáint-Hyácinthe'; $encoding=mb_detect_encoding($guesstitlestring); if ($encoding!=='UTF-8') $guesstitlestring=mb_convert_encoding($guesstitlestring,'UTF-8',$encoding); echo "DEBUG1 $guesstitlestring\n"; $guesstitlestring=mb_strtoupper($guesstitlestring); echo "DEBUG2 $guesstitlestring\n"; 

Результат:

 DEBUG1 Le Courrier de Sáint-Hyácinthe DEBUG2 LE COURRIER DE S?INT-HY?CINTHE 

Я не понимаю, почему это происходит? Я пытаюсь быть настолько осторожным, насколько могу, с кодировкой. Строка задается сначала как UTF-8, проверяется и может быть преобразована в UTF-8. Это кошмар!

ОБНОВИТЬ

Поэтому я понял, что это вызвано сочетанием ввода аргументов через консоль и аргументов, возвращающихся из консоли. Таким образом, они были искажены как по пути, так и к выходу. Решение состоит в том, чтобы не вводить ни один из аргументов таким образом или не приводить аргументы таким образом.

Спасибо всем за помощь в решении этой проблемы!

Вместо strtoupper()/mb_strtoupper() используйте mb_convert_case() поскольку преобразование в верхнем регистре очень сложно в разных кодировках, также убедитесь, что ваша строка IS UTF-8.

 $content = 'Le Courrier de Sáint-Hyácinthe'; mb_internal_encoding('UTF-8'); if(!mb_check_encoding($content, 'UTF-8') OR !($content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8' ), 'UTF-8', 'UTF-32'))) { $content = mb_convert_encoding($content, 'UTF-8'); } // LE COURRIER DE SÁINT-HYÁCINTHE echo mb_convert_case($content, MB_CASE_UPPER, "UTF-8"); 

Рабочий пример: http://3v4l.org/enEfm#v443

См. Также мой комментарий на веб-сайте PHP о конвертере: http://www.php.net/manual/function.utf8-encode.php#102382

Он работает для меня, но только тогда, когда сам файл php сохраняется как UTF-8, и когда терминал, на котором я нахожусь, ожидает UTF-8. Я думаю, что для вас происходит то, что файл сохраняется как ISO-8859-1, и ваш терминал ожидает ISO-8859-1.

Во-первых, mb_detect_encoding фактически не работает для этой строки. Даже когда PHP-файл не является UTF-8, он все еще сообщает об этом как UTF-8.

Когда вы печатаете строчную строчку, она печатает символы ISO-8859-1, и ваш терминал отображает их просто отлично. Затем, когда вы конвертируете в верхний регистр с использованием UTF-8, он становится искалеченным.

Я создал две версии этого файла. Я сохранил его, используя свой текстовый редактор в ISO-8859-1, как iso-8859-1.php . Затем я использовал iconv для преобразования всего файла в UTF-8 и сохранил его как utf-8.php

 iconv iso-8859-1.php --from iso-8859-1 --to UTF-8 > utf-8.php 

Я добавил строку для печати результата, который возвращает mb_detect_encoding.

 $ file iso-8859-1.php iso-8859-1.php: PHP script, ISO-8859 text $ php iso-8859-1.php ENCODING: UTF-8 DEBUG1 Le Courrier de S int-Hy cinthe DEBUG2 LE COURRIER DE S?INT-HY?CINTHE $ file utf-8.php utf-8.php: PHP script, UTF-8 Unicode text $ php utf-8.php ENCODING: UTF-8 DEBUG1 Le Courrier de Sáint-Hyácinthe DEBUG2 LE COURRIER DE SÁINT-HYÁCINTHE 

Мой терминал действительно ожидает текст UTF-8, поэтому, когда я печатаю текст ISO-8859-1, он становится искалеченным. Все работает правильно, когда файл сохраняется как utf-8, и терминал ожидает utf-8.

Собственно, то, что здесь работает, просто

 <?php mb_internal_encoding('UTF-8'); $x='Le Courrier de Sáint-Hyácinthe'; echo mb_strtoupper( $x ) . "\n"; 

выходы

 LE COURRIER DE SÁINT-HYÁCINTHE 

здесь он работает напрямую, но, возможно, в вашем случае вам нужно добавить utf8_encode :

 $x = utf8_encode( 'Le Courrier de Sáint-Hyácinthe' ); 

Альтернатива, которая работает здесь без MB,

 <?php echo strtoupper(str_replace('á', 'Á', 'Le Courrier de Sáint-Hyácinthe'));