Удаление нечитаемых символов при помощи iconv

При массовом получении данных из сети часто возникает ситуация когда в неподконтрольный нам HTML-код страниц ушлые вебмастера допускают попадание различного рода нечитаемых спецсимволов, символов кодировки, отличной от основной кодировки страницы и т. п. Удалить такие символы можно при помощи библиотеки ICONV, которую мы все равно будем применять для преобразования страницы из ее кодировки в требуемую для нашей системы. К примеру, преобразование кодировки из utf-8 в windows-1251 и удаление нечитаемых символов:

$html = iconv('utf-8', 'windows-1251//IGNORE', $html);

Решение проблемы преобразования данных из UTF-8 в KOI8-R

Предположим, у нас есть сайт в кодировке KOI8-R, на котором нам нужно вывести данные, полученные из внешнего источника (например, из RSS-ленты) в кодировке UTF8. На первый взгляд задача решается тривиально:

$sKOIR = iconv( 'UTF-8', 'KOI8-R', $sUTF8 );

Однако тут есть небольшой подводный камень: кодировка UTF-8 содержит значительно большее количество символов, чем KOI8-R. Так, например, в KOI8-R отсутствует символ номера - «№». Поэтому при попытке конвертации, UTF8-строки, содержащей символ «№», iconv сгенерирует замечание следующего содержания: 

Notice: iconv(): Detected an illegal character in input string in file.php on line x

Данное замечание говорит нам о том, что iconv не может найти аналога для символа «№» в KOI8-R.


Тривиальным решением проблемы тут может послужить представление проблемного символа в транслитерации (для символа «№» аналогом будет «No»), или же вообще полное его игнорирование:

$sKOIR = iconv( 'UTF-8', 'KOI8-R//TRANSLIT', $sUTF8 );
$sKOIR = iconv( 'UTF-8', 'KOI8-R//IGNORE', $sUTF8 );

Конечно, такой подход нельзя назвать серьёзным. К нашему счастью современные браузеры умеют понимать символы Unicode, представленные в виде HTML-сущностей (HTML Entities). Естественно, что отображение HTML-сущностей никак не зависит от текущей кодировки страницы. Так, например, символ «№» в виде HTML-сущности можно записать как “№”.
Для того, что бы преобразовать UTF8-строку в HTML-сущности в PHP существует функция mb_convert_encoding:

$sKOI8 = mb_convert_encoding($sUTF8, 'HTML-ENTITIES', 'UTF-8');

Отдельно стоит заметить, что mb_convert_encoding не экранирует зарезервированные символы HTML. Поэтому для решения поставленной выше задачи функцию mb_convert_encoding стоит использовать в связке с htmlentities:

$str = htmlentities($sUTF8, ENT_COMPAT, 'UTF-8');
$sKOI8 = mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8');