Перекодировка cp1251 в UTF8
- 12 May, 2008
- Posted in PHP
Tags : PHP, UTF-8- 23 Comments
Сегодня столкнулся с проблемой перекодировки русского текста из cp1251 (windows-1251) в UTF8. Решение нашел быстро. Как всегда нельзя переоценить роль Google;)
Ранее пользовался iconv(“CP1251″, “UTF-8″, $text_for_convert), но, как известно iconv даёт большую нагрузку на сервер и работает медленнее чем представленная ниже функция.
function cp1251_to_utf8 ($txt) {
$in_arr = array (
chr(208), chr(192), chr(193), chr(194),
chr(195), chr(196), chr(197), chr(168),
chr(198), chr(199), chr(200), chr(201),
chr(202), chr(203), chr(204), chr(205),
chr(206), chr(207), chr(209), chr(210),
chr(211), chr(212), chr(213), chr(214),
chr(215), chr(216), chr(217), chr(218),
chr(219), chr(220), chr(221), chr(222),
chr(223), chr(224), chr(225), chr(226),
chr(227), chr(228), chr(229), chr(184),
chr(230), chr(231), chr(232), chr(233),
chr(234), chr(235), chr(236), chr(237),
chr(238), chr(239), chr(240), chr(241),
chr(242), chr(243), chr(244), chr(245),
chr(246), chr(247), chr(248), chr(249),
chr(250), chr(251), chr(252), chr(253),
chr(254), chr(255)
);
$out_arr = array (
chr(208).chr(160), chr(208).chr(144), chr(208).chr(145),
chr(208).chr(146), chr(208).chr(147), chr(208).chr(148),
chr(208).chr(149), chr(208).chr(129), chr(208).chr(150),
chr(208).chr(151), chr(208).chr(152), chr(208).chr(153),
chr(208).chr(154), chr(208).chr(155), chr(208).chr(156),
chr(208).chr(157), chr(208).chr(158), chr(208).chr(159),
chr(208).chr(161), chr(208).chr(162), chr(208).chr(163),
chr(208).chr(164), chr(208).chr(165), chr(208).chr(166),
chr(208).chr(167), chr(208).chr(168), chr(208).chr(169),
chr(208).chr(170), chr(208).chr(171), chr(208).chr(172),
chr(208).chr(173), chr(208).chr(174), chr(208).chr(175),
chr(208).chr(176), chr(208).chr(177), chr(208).chr(178),
chr(208).chr(179), chr(208).chr(180), chr(208).chr(181),
chr(209).chr(145), chr(208).chr(182), chr(208).chr(183),
chr(208).chr(184), chr(208).chr(185), chr(208).chr(186),
chr(208).chr(187), chr(208).chr(188), chr(208).chr(189),
chr(208).chr(190), chr(208).chr(191), chr(209).chr(128),
chr(209).chr(129), chr(209).chr(130), chr(209).chr(131),
chr(209).chr(132), chr(209).chr(133), chr(209).chr(134),
chr(209).chr(135), chr(209).chr(136), chr(209).chr(137),
chr(209).chr(138), chr(209).chr(139), chr(209).chr(140),
chr(209).chr(141), chr(209).chr(142), chr(209).chr(143)
);
$txt = str_replace($in_arr,$out_arr,$txt);
return $txt;
}
Отказаться от iconv вынудило еще то, что в определенный момент при перекодировании из windows-1251 в UTF-8 без видимых причин, данная функция стала возвращать пустую строку.
З.Ы. Если поменять местами $in_arr и $out_arr, то функция заработает “в обратном направлении”, т.е. будет преобразовывать UTF-8 в CP-1251.
Большое спасибо за функцию!!!
Реально выручил!
Спасибо огромное)
Очень помогло)) iconv нереально глючная(
У меня такая проблема… на сайте есть регистрация, и если пользователь регистрируясь указывает в логине или пароле русские символы, то при авторизации (когда из БД вытаскивается логин и пароль) происходит ошибка – пользователь не может зайти на сайт!!! MySQL база работает под UTF-8 может ли это быть из-за кодировки? И могу ли я испраить это с помощю вашего скрипта, и ели да то как? Это мне перед заносом в БД нужно переменные из формы перекодировать вот так: function cp1251_to_utf8 ($login) {
$in_arr = array (…
Если текст на вашем сайте выводится в кодировке cp-1251, то перекодировка полученных от пользователя данных должна помочь.
Еще попробуйте сразу после коннекта с базой выполнить:
mysql_query(“SET NAMES ‘CP-1251′”);
Думаю, тогда можно будет обойтись без перекодировки.
Отличная функция, спасибо. Но здесь представлен только русский язык, мне еще нужно добавить буквы украинского алфавита, например “і”, “є”, “ї”.
Как узнать их код, чтобы записать во второй массив? В первый я их записываю с помощью функции ord()
Спасибо
шестнадцатиричный код можно узнать в Word’е:
после символа нажать Alt+X и символ измениться на код.
кстати, я использую немного другой вариант данной функции:
видете, что в первом массиве код 208 стоит самым первым(?!) это потому, что если его поставить позже, то он сначала навставляет 208 в результат, а потом попортит НОРМАЛЬНЫЙ перевод ко всем бабушкам… поэтому для новых символов я пошел другим путём
в верхний массив добавляю код, а в нижний уникод… лучше на примере:
chr(194), chr(185), chr(176),
chr(195), chr(196), chr(151), chr(150),
chr(171), chr(187), chr(222),
соответствует
chr(208).chr(146), ‘№’, ‘°’,
chr(208).chr(147), chr(208).chr(148), ‘—’,chr(0).chr(45),
‘«’,'»’, ‘Ю’,
примечание: тут код десятичный, поэтому надо ещё через calc код пересчитать
а в целом ОГРОМНОЕ СПАСИБО!
млииин, эксплорер с чистой совестью мой код съел и в буквы превратил…
)
повторю вторую часть навставляв пробелов между &# и кодом
chr(208).chr(146), ‘&# 8470;’, ‘&# 0176;’,
chr(208).chr(147), chr(208).chr(148), ‘&# 8212;’, chr(0).chr(45),
‘&# 0171;’,'&# 0187;’, ‘&# 1070;’,
Спасибо! Сегодня обновлю обновлю статью!
Моно попробовать вот так (в целях уменьшения кода):
function UTF8Decode($cp1251){
$utf8=”;
for($i=0;$i= 240 && $c <= 255) $utf8.=chr(209).chr($c-48);
elseif(($c=192)||$c==168) $utf8.=chr(208).chr($c-112);
}
return $utf8;
}
>>> Моно попробовать вот так (в целях уменьшения кода)
Это тот-же код, только не на массивах
Полностью поправил, вот исходник:
function UTF8Decode($cp1251){
$utf8=”";
for($i=0;$i191&&$c239&&$c<256)$utf8.=chr(209).chr($c-112);
else $utf8.=$cp1251[$i];
}
return $utf8;
}
Спасибо. Очень помогло.
tiger-nick
странная последняя функция
function UTF8Decode($cp1251){
php Говорит ошибка syntax error, unexpected ‘)’, expecting ‘;’ в строке for($i=0;$i191&&$c239&&$c<256)$utf8.=chr(209).chr($c-112);
может я чего то не понимаю, а else у вас к чему привязанно?
Чтобы вытащить описания книг из FB2, которые в UTF8,
воспользовался этой функцией. Громоздко, но всегда
можно вставить дополнительные сочетания символов.
Функция на фоксе, но это не важно.
FUNCTION UTF8TOCP1251
PARAMETERS _TXT
DECLARE MA[69,2]
MA[01,1]=”Рђ” && А
MA[02,1]=”Р‘’” && Б
MA[03,1]=”Р’” && В
MA[04,1]=CHR(208)+CHR(147) && Г Р“
MA[05,1]=CHR(208)+CHR(148) && Д Р”
MA[06,1]=”Р•” && Е
MA[07,1]=”РЃ” && Ё
MA[08,1]=”Р–” && Ж
MA[09,1]=”Р—” && З
MA[10,1]=”Рљ” && К
MA[11,1]=”Р” && И
MA[12,1]=”Р™” && Й
MA[13,1]=”Р›” && Л
MA[14,1]=”Рњ” && М
MA[15,1]=”Рќ” && Н
MA[16,1]=”Рћ” && О
MA[17,1]=”Рџ” && П
MA[18,1]=”Р ” && Р
MA[19,1]=”РЎ” && С
MA[20,1]=”Рў” && Т
MA[21,1]=”РЈ” && У
MA[22,1]=”Р¤” && Ф
MA[23,1]=”РҐ” && Х
MA[24,1]=”Р¦” && Ц
MA[25,1]=”Р§” && Ч
MA[26,1]=”Р” && Э
MA[27,1]=”РЁ” && Ш
MA[28,1]=”Р©” && Щ
MA[29,1]=”Р®” && Ю
MA[30,1]=”Р«” && Ы
MA[31,1]=”Р¬” && Ь
MA[32,1]=”РЄ” && Ъ
MA[33,1]=”РЇ” && Я
MA[34,1]=”Р°” && а
MA[35,1]=”Р±” && б
MA[36,1]=”РІ” && в
MA[37,1]=”Рі” && г
MA[38,1]=”Рґ” && д
MA[39,1]=”Рµ” && е
MA[40,1]=”С‘” && ё
MA[41,1]=”Р¶” && ж
MA[42,1]=”Р·” && з
MA[43,1]=”Рё” && и
MA[44,1]=”Р№” && й
MA[45,1]=”Рє” && к
MA[46,1]=”Р»” && л
MA[47,1]=”Рј” && м
MA[48,1]=”РЅ” && н
MA[49,1]=”Рѕ” && о
MA[50,1]=”Рї” && п
MA[51,1]=”СЂ” && р
MA[52,1]=”СЃ” && с
MA[53,1]=”С‚” && т
MA[54,1]=”Сѓ” && у
MA[55,1]=’С„’ && ф
MA[56,1]=”С…” && х
MA[57,1]=”С†” && ц
MA[58,1]=”С‡” && ч
MA[59,1]=”СЌ” && э
MA[60,1]=”С€” && ш
MA[61,1]=”С‰” && щ
MA[62,1]=”СЋ” && ю
MA[63,1]=”С‹” && ы
MA[64,1]=”СЊ” && ь
MA[65,1]=”СЉ” && ъ
MA[66,1]=”СЏ” && я
MA[67,1]=’–’ && –
MA[68,1]=’ – ‘ && –  –
MA[69,1]=”— &&CHR(194) && – В
********************
MA[01,2]=”А”
MA[02,2]=”Б”
MA[03,2]=”В”
MA[04,2]=”Г”
MA[05,2]=”Д”
MA[06,2]=”Е”
MA[07,2]=”Ё”
MA[08,2]=”Ж”
MA[09,2]=”З”
MA[10,2]=”К”
MA[11,2]=”И”
MA[12,2]=”Й”
MA[13,2]=”Л”
MA[14,2]=”М”
MA[15,2]=”Н”
MA[16,2]=”О”
MA[17,2]=”П”
MA[18,2]=”Р”
MA[19,2]=”С”
MA[20,2]=”Т”
MA[21,2]=”У”
MA[22,2]=”Ф”
MA[23,2]=”Х”
MA[24,2]=”Ц”
MA[25,2]=”Ч”
MA[26,2]=”Э”
MA[27,2]=”Ш”
MA[28,2]=”Щ”
MA[29,2]=”Ю”
MA[30,2]=”Ы”
MA[31,2]=”Ь”
MA[32,2]=”Ъ”
MA[33,2]=”Я”
MA[34,2]=”а”
MA[35,2]=”б”
MA[36,2]=”в”
MA[37,2]=”г”
MA[38,2]=”д”
MA[39,2]=”е”
MA[40,2]=”ё”
MA[41,2]=”ж”
MA[42,2]=”з”
MA[43,2]=”и”
MA[44,2]=”й”
MA[45,2]=”к”
MA[46,2]=”л”
MA[47,2]=”м”
MA[48,2]=”н”
MA[49,2]=”о”
MA[50,2]=”п”
MA[51,2]=”р”
MA[52,2]=”с”
MA[53,2]=”т”
MA[54,2]=”у”
MA[55,2]=”ф”
MA[56,2]=”х”
MA[57,2]=”ц”
MA[58,2]=”ч”
MA[59,2]=”э”
MA[60,2]=”ш”
MA[61,2]=”щ”
MA[62,2]=”ю”
MA[63,2]=”ы”
MA[64,2]=”ь”
MA[65,2]=”ъ”
MA[66,2]=”я”
MA[67,2]=”- ”
MA[68,2]=” – ”
MA[69,2]=”…”
FOR I=1 TO 69
_TXT= STRTRAN( _TXT, MA[I,1], MA[I,2] )
ENDFOR
RETURN _TXT
Для украинских символов коды:
Маленькое “и”: і – 0456
Большое “И: І – 0406
Маленькое “е”: є – 0454
Большое “Е”: Є – 0404
Маленькое “йи”: ї – 0457
Большое “ИЙ”: Ї – 0407
Спасибо… все мозги себе откомпостировал… iconv стал возвращать пустую строку(( теперь все ок))
Спасибо за функцию
Спасибо. Функция рулит.
Что бы не ломать голову о порядке следования подстановок для str_replace нужно использовать strtr
Для примера, я добавил знак Номер- №
Word выдает какие-то не те цифры, скажем для того же символа “номер” он сообщает нам x2116, а на самом деле это xE28496. Правильные цифры выдает notepad++ – создаем новый документ UTF-8 без BOM, печатаем нужную букву и потом смотрим файл в hex виде (можно в тотал командере по F3 и потом перейти в hex режим, нажав 3 (или в меню)
class TConv
{
// таблицы символов, см. конец этого файла
static $CP1251;
static $UTF8;
static $WIN2UTF_TABLE = false;
static function win2utf ( $aString )
{ // http://mihalytch.org.ua/programming/php/convert-cp1251-utf8.html
if ( !self::$WIN2UTF_TABLE )
self::$WIN2UTF_TABLE = array_combine( self::$CP1251, self::$UTF8 );
$Result = strtr( $aString, self::$WIN2UTF_TABLE );
return $Result;
}
}
TConv::$CP1251 = array (
chr(208), // CAPITALL ER
chr(185), // NUMERO SIGN
chr(192), chr(193), chr(194),
chr(195), chr(196), chr(197), chr(168),
chr(198), chr(199), chr(200), chr(201),
chr(202), chr(203), chr(204), chr(205),
chr(206), chr(207), chr(209), chr(210),
chr(211), chr(212), chr(213), chr(214),
chr(215), chr(216), chr(217), chr(218),
chr(219), chr(220), chr(221), chr(222),
chr(223), chr(224), chr(225), chr(226),
chr(227), chr(228), chr(229), chr(184),
chr(230), chr(231), chr(232), chr(233),
chr(234), chr(235), chr(236), chr(237),
chr(238), chr(239), chr(240), chr(241),
chr(242), chr(243), chr(244), chr(245),
chr(246), chr(247), chr(248), chr(249),
chr(250), chr(251), chr(252), chr(253),
chr(254), chr(255)
);
TConv::$UTF8 = array (
chr(208).chr(160), // // CAPITALL ER
chr(226).chr(132).chr(150), // NUMERO SIGN
chr(208).chr(144), chr(208).chr(145), chr(208).chr(146),
chr(208).chr(147), chr(208).chr(148),
chr(208).chr(149), chr(208).chr(129), chr(208).chr(150),
chr(208).chr(151), chr(208).chr(152), chr(208).chr(153),
chr(208).chr(154), chr(208).chr(155), chr(208).chr(156),
chr(208).chr(157), chr(208).chr(158), chr(208).chr(159),
chr(208).chr(161), chr(208).chr(162), chr(208).chr(163),
chr(208).chr(164), chr(208).chr(165), chr(208).chr(166),
chr(208).chr(167), chr(208).chr(168), chr(208).chr(169),
chr(208).chr(170), chr(208).chr(171), chr(208).chr(172),
chr(208).chr(173), chr(208).chr(174), chr(208).chr(175),
chr(208).chr(176), chr(208).chr(177), chr(208).chr(178),
chr(208).chr(179), chr(208).chr(180), chr(208).chr(181),
chr(209).chr(145), chr(208).chr(182), chr(208).chr(183),
chr(208).chr(184), chr(208).chr(185), chr(208).chr(186),
chr(208).chr(187), chr(208).chr(188), chr(208).chr(189),
chr(208).chr(190), chr(208).chr(191), chr(209).chr(128),
chr(209).chr(129), chr(209).chr(130), chr(209).chr(131),
chr(209).chr(132), chr(209).chr(133), chr(209).chr(134),
chr(209).chr(135), chr(209).chr(136), chr(209).chr(137),
chr(209).chr(138), chr(209).chr(139), chr(209).chr(140),
chr(209).chr(141), chr(209).chr(142), chr(209).chr(143)
);
Разобрался с кодировками, Word все правильно показывает, только это не UTF-8, а UNICODE
Правила преобразования UNICODE в UTF-8 можно глянуть тут http://en.wikipedia.org/wiki/UTF-8
Итак, для нашей буквы “Номер” UNICODE значение 2116 (Hex)
Оно подпадает под правило U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
При помощи calc преобразуем 2116 (Hex) в двоичный вид 10000100010110 (Bin)
Вставлеям наши биты в маску
U+FFFF 1110[0010] 10[000100] 10[010110]
Полученное число запихиваем снова в calc 111000101000010010010110 и получаем E28496 hex,
это и есть искомый код нашего символа в UTF-8
Его можно записать в виде chr(0xE2).chr(0×84).chr(0×96) не преобразуя в Dec
UNICODE таблицы можно брать вот тут http://www.unicode.org/charts
В частности, наш многострадальный символ “Номер” находится вот в этом документе
http://www.unicode.org/charts/PDF/U2100.pdf
Вот кириллические символы http://www.unicode.org/charts/PDF/U0400.pdf
Пасиба, действительно помогла!!!
Огромнейшее спасибо!От всего сердца)
Спасибо, функиця очень пригодилась)