Преобразование из сопоставления mysql cp1251_general_ci (Windows-1251) в UTF-8 php

У меня есть строка mysql varchar(50) в сопоставлении cp1251_general_ci. После mysql_fetch_row в php я получил $ строку. Затем я делаю следующее:

echo mb_detect_encoding($string,'CP1251,UTF-8,Windows-1251'); // echoes Windows-1251
$string = mb_convert_encoding($string, 'UTF-8', 'Windows-1251');
echo mb_detect_encoding($string,'CP1251,UTF-8,Windows-1251'); // again echoes Windows-1251

Почему во второй раз строка не UTF-8?

Я тоже пробовал

$string = iconv('Windows-1251', 'UTF-8', $string);

Но опять же, у нас есть кодировка Windows-1251.

И в конечном результате я получил неправильную кодировку в моем имени файла, которая состоит из переменной $string.

Как я могу преобразовать из сопоставления mysql cp1251_general_ci (Windows-1251) в UTF-8?

PS

echo $string; \\ echoes ������
echo bin2hex($string); \\ echoes cce5e3e0f4eeed
$string = mb_convert_encoding($string, 'UTF-8', 'Windows-1251');
echo $string; \\ echoes Мегафон
echo bin2hex($string); \\ echoes  d09cd0b5d0b3d0b0d184d0bed0bd

Но

fopen("../tmp/$string.log", "w");

создает файл.../tmp/??????????????.log (в linux)

1 ответ

Решение

Нашел причину этой странной ситуации!

Вкратце: если вы видите правильную кодированную строку UTF-8 на сервере (в терминале) в нечитаемых символах - проверьте языковой стандарт сервера. И если вы видите странное поведение метода mb_detect_encoding(), не забывайте об этом - mb_detect_encoding не дает вам точного определения кодировки строки.

Причиной неправильной кодировки в имени файла: .../tmp/??????????????. Log файл является локаль на сервере! Вот результат команды локали на сервере, где расположен файл:

$ locale
LANG=
LC_CTYPE="C"
LC_COLLATE="C"
LC_TIME="C"
LC_NUMERIC="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=

Для правильного отображения символов UFT-8 в именах файлов на сервере языковой стандарт сервера также должен быть utf-8.

И обо всем обращении в вопросе. Оба метода:

iconv('Windows-1251', 'UTF-8', $string);

а также

mb_convert_encoding($string, 'UTF-8', 'Windows-1251');

отлично работает в этом случае.

Единственный вопрос, почему второе эхо

echo mb_detect_encoding($string,'CP1251,UTF-8,Windows-1251'); // echoes Windows-1251
$string = mb_convert_encoding($string, 'UTF-8', 'Windows-1251');
echo mb_detect_encoding($string,'CP1251,UTF-8,Windows-1251'); // again echoes Windows-1251

не UTF-8?

И ответ - mb_detect_encoding не дает точного определения кодировки строки

Другие вопросы по тегам