Переводя текст из одной кодовой страницы в другую, используя PHP функцию iconv()
, можно столкнуться с проблемой — iconv()
не возвращает ничего. На самом деле, возвращает, но не ожидаемую строку, а логическое значение false
. Почему так происходит и что с этим делать?
Предлагаю рассмотреть описанную проблему на конкретном примере: перекодировка текстовой строки из кодовой страницы UTF-8 в KOI8-R. Это частая задача, с которой сталкиваются разработчики, например, при подготовке текста, полученного из формы обратной связи, для отправки его в виде текста письма по электронной почте.
<?php
$text = '« Potato #345 » — a simple portrait of an organic Irish spud — reportedly sold for €1 million.';
echo iconv('UTF-8', 'KOI8-R', $text);
?>
Начиная с версии PHP 5.4, такой код не выведет ничего. Но если посмотреть дамп, то будет видно, что функция iconv()
возвращает значение false
. А если включен режим вывода сообщений об ошибках, то вы увидите Notice: iconv(): Detected an illegal character in input string in ...
.
<?php
var_dump(iconv('UTF-8', 'KOI8-R', $text));
?>
Это происходит в тех случаях, когда конвертируемая строка содержит символы, отсутствующие в целевой кодовой странице. В строке из примера я выделил символы, приводящие к появлению ошибки перекодировки из UTF-8 в кодовую страницу KOI8-R:
« Potato #345 » — a simple portrait of an organic Irish spud — reportedly sold for €1 million.
До версии PHP 5.4, в случае, если функция iconv()
встречала проблемные символы в перекодируемой строке, то она возвращала часть строки до первого найденного символа.
Зная об особенности работы функции iconv()
, можно выбрать один из следующих методов решения потенциальной проблемы:
- предварительно удалить из перекодируемой строки символы, приводящие к ошибке;
- использовать специальные флаги, управляющие работой функции.
Конечно, при желании можно использовать первый метод, но он не универсален, так как придётся учитывать все символы, отсутствующие в целевой кодовой странице. Гораздо удобнее и правильно использовать второй метод.
Функция iconv()
поддерживает два флага, добавляемых к указываемой целевой кодовой странице:
//TRANSLIT
– включает режим транслитерации, выполняющий замену символов, которые не могут быть представлены в целевой кодовой странице, на один или несколько символов, наиболее близких по внешнему виду;//IGNORE
– включает режим, удаляющий символы, которые не могут быть представлены в целевой кодовой странице.
Следует учитывать, что работа режима //TRANSLIT
зависит от реализации iconv()
в системе, поэтому этот режим может работать некорректно или не работать совсем, что приведёт к появлению ошибки. Поэтому надёжнее указывать сразу оба флага:
<?php
echo iconv('UTF-8', 'KOI8-R//TRANSLIT//IGNORE', $text);
?>
Результат выполнения функции iconv()
с флагами выглядит так:
« Potato #345 » – a simple portrait of an organic Irish spud – reportedly sold for EUR1 million.
Думаю, что теперь у вас не возникнет вопроса о том, что делать и почему “iconv()
не возвращает ничего”.