Конвертация кодировок на лету
Недавно столкнулся с интересной задачей. Конвертация кодировок налету.
Мои скрипты, отрабатывающие по CRON’у сохранены в кодировке Win-1251. Весь вывод скрипта является отчетом, который автоматически приходит на мою гугл-почту, которая открывает письма как UTF-8. В итоге отчеты были нечитабельны. Не конвертировать же каждую строку при выводе в UTF-8?
Великий гугл быстро помог разобраться с моей проблемой.
В самом начале скрипта нужно добавить всего 3 строки:
iconv_set_encoding("internal_encoding", "cp1251"); //внутренняя кодировка iconv_set_encoding("output_encoding", "UTF-8"); //внешняя кодировка ob_start("ob_iconv_handler"); // старт буферизации вывода |
В итоге весь вывод буферизуется. При завершении работы скрипта буфер очищается и все содержимое конвертируется из cp1251 в UTF-8.
Если вы захотите использовать это решение – помните о возможных проблемах.
Буферизация
Весь вывод мы буферизуем, и пока буфер не заполнен (или принудительно не очищен), результаты скрипта на экран не выводятся. То есть, при запуске скрипта из командной строки экран будет пустым, пока сам буфер не очистится, или пока скрипт не отработает.
Предупреждения не сохраняются в буфере
Предупреждения не буферизуются. Наглядней всего продемонстрировать это на примере. Пусть имеется массив из двух элементов. Пройдемся циклом от 1 до 3 и попытаемся получить несуществующий элемент:
<?php // создаем массив из ДВУХ элементов $arr = array(1 => 10, 2 => 20); // пытаемся получить ТРИ элемента for ($i=1; $i<=3; $i++){ echo $i." => ".$arr[$i]."\r\n"; } ?> |
Получим на выходе:
1 => 10
2 => 20
PHP Notice: Undefined offset: 3 in error.php on line 6 // Ошибка
3 =>
Если же добавить буферизацию вывода:
<?php iconv_set_encoding("internal_encoding", "cp1251"); iconv_set_encoding("output_encoding", "UTF-8"); ob_start("ob_iconv_handler"); // создаем массив из ДВУХ элементов $arr = array(1 => 10, 2 => 20); // пытаемся получить ТРИ элемента for ($i=1; $i<=3; $i++){ echo $i." => ".$arr[$i]."\r\n"; } ?> |
То получим вначале все ошибки, а потом содержимое буфера:
PHP Notice: Undefined offset: 3 in error.php on line 9 // Сначала ошибка
1 => 10
2 => 20
3 =>
Столкнулся с проблемой в некорректной обработки перекодировки на PHP 5.4 и 5.5.
На 5.3 все работало отлично, помогает замена функции перекодировки, но это морока менять в проекте.
@Antonio
Когда писал статью, на сервере был установлен PHP 5.3
Сейчас — 5.4; Всё работает без ошибок.
Проверил локально на версии 5.5 — аналогично. Может проблема не в этой функции?