Сконвертировать строку в utf8
Имеется строка в массиве со значением Алмасу буферіне көшіру. Есть алгоритм, который конвертирует все строки из кодировки 1251 в UTF8.
function json_fix_cyr($var) {
if (is_array($var)) {
$new = array();
foreach ($var as $k => $v) {
$new[json_fix_cyr($k)] = json_fix_cyr($v);
}
$var = $new;
} elseif (is_object($var)) {
$vars = get_object_vars($var);
foreach ($vars as $m => $v) {
$var->$m = json_fix_cyr($v);
}
} elseif (is_string($var)) {
$var = iconv('cp1251', 'utf-8', $var); // здесь происходит конвертация
}
return $var;
}
Требуется для данной строки сделать исключение, но пока не понимаю, как отловить определённый utf8 символ в строке. Если делаю так:
$new = '';
for ($b = 0; $b < strlen($var); $b++)
if ($var[$b] === 'ө')
$new .= 'ө';
else
$new .= iconv('cp1251', 'utf-8', $var[$b]);
$var = $new;
то символ ө конвертируется в вопросительный знак. Если конвертацию не делать, в других местах возникают ошибки. Однако, если просто добавить данный символ к конвертированной строке, то далее он отображается без ошибок. Как отловить нужные мне символы?
Ответы (2 шт):
Существует несколько вариантов cp1251. Буква ө присутствует в казахском и татарском вариантах. Функция iconv ничего об этом не знает. То есть в таблице соответствия символов cp1251 символам utf-8 нет буквы ө.
В вашем случае речь о казахской кодировке. Вы можете посмотреть (на машине, где будет работать ваш скрипт) какие кодировки поддерживает iconv, набрав в консоли iconv -l. Если там найдётся KZ-1048, то можно конвертировать так: iconv('KZ-1048', 'UTF-8', $var). Если кодировка KZ-1048 отсутствует, то её, скорее всего, можно как-то установить. Я не знаю как это делается, гуглите.
Костыльное решение (на разок, чтобы перевести всё в utf и забыть про муки с разными языками ваших пользователей) заключается в том, чтобы сделать замену одного неудобного символа (на самом деле их там больше) вручную.
Вы двигались в правильном направлении, но, скорее всего, не учли, что текст в вашем скрипте тоже в какой-то кодировке. Современные редакторы кода обычно по умолчанию сохраняют ваш код в utf-8. То есть строка 'ө' в вашем коде это utf-8 символ.
В казахской кодировке ө стоит на месте ґ в стандартном cp1251 (кстати, что у вас получалось при простой конвертации iconv('cp1251', 'utf-8', $var)?). То есть ord('ө') === 180.
<?php // файл в KZ-1048
$text = 'Алмасу буферіне көшіру';
$result = '';
for ($i = 0; $i < strlen($text); ++$i) {
if (ord($text[$i]) === 180) {
$result .= mb_chr(1257, 'UTF-8'); // ө в utf-8
} else {
$result .= iconv('cp1251', 'utf-8', $text[$i]);
}
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
Не забывайте про заглавную Ө и может быть какие-нибудь ещё символы, которые отличаются от cp1251.
Чтобы сконвертировать строку в utf-8, надо знать исходную кодировку этой строки. И дальше воспользоваться одной из функций перекодирования, доступных в РНР. Например
// из Windows-1251 в UTF-8
$string = iconv('cp1251', 'utf-8', $string);
или
// из UTF-16 в UTF-8
$string = mb_convert_encoding($string, 'utf-8', 'utf-16');