iconv и битый utf-8

DiTHER

bang bang
iconv и битый utf-8

Может кто в курсе как заставить iconv не генерировать ошибку уровня E_NOTICE когда ему подсовывают UTF, в котором есть "обрезаный символ". Т.е. разрезанный пополам?

[Notice: iconv(): Detected an incomplete multibyte character in input string in /ro...]

Легко воспроизвести - подсуньте ему русский символ koi и скажите что это utf

PHP:
iconv('utf-8','cp1251','ф');
//IGNORE при этом не помогает. Или может быть какой-то есть спопоб нахождения этих неполных символов? иконв же находит как-то..

Причем в шелле 'iconv -c' конвертит что куда хочу.
 

SiMM

Новичок
PHP:
function StripBadUTF8($str){ // (C) SiMM, based on ru.wikipedia.org/wiki/Unicode
  $ret = '';
  for ($i = 0; $i<strlen($str); ){
    $tmp = $str{$i++};
    $ch = ord($tmp);
    if ($ch>0x7F) {
      if     ($ch<0xC0) continue;
      elseif ($ch<0xE0) $di = 1;
      elseif ($ch<0xF0) $di = 2;
      elseif ($ch<0xF8) $di = 3;
      elseif ($ch<0xFC) $di = 4;
      elseif ($ch<0xFE) $di = 5;
      else continue;

      for ($j=0; $j<$di; $j++){
        $tmp .= $ch = $str{$i+$j};
        $ch = ord($ch);
        if ($ch<0x80 || $ch>0xB0) continue 2;
      }
      $i += $di;
    }
    $ret .= $tmp;
  }
  return $ret;
}
PS: код сильно не проверял (т.е. не проверял вообще - лениво придумывать тесты) - но, надеюсь, идея и так ясна и очевидна.
PPS: сделать это одним регулярником - не осилил - может кто сможет? :)
 

SiMM

Новичок
> @iconv('utf-8','cp1251','ф');
Чо-то мне взбрело в голову, что такой простой вариант его не устроит ;)
 

DiTHER

bang bang
ну уж такой то вариант я пожалуй попробовал :)

+E_STRICT :)

SiMM, благодарю. Идея ясна, ясна и была. Просто думал вдруг кто уже написал чего.. Сейчас поэкспериментируемс..

-~{}~ 28.06.05 10:10:

да и кстати даже с собакой - iconv не будет конвертить дальше, встав на кривом символе.

-~{}~ 28.06.05 10:21:

ух ты. надо подружится с wikipedia..
 

Demiurg

Guest
>да и кстати даже с собакой - iconv не будет конвертить дальше, встав на кривом символе.
ты забыл про //ignore
 

DiTHER

bang bang
нет не забыл. пробовал и ignore и собаку.
ошибка уровня E_NOTICE и остановка на битом символе.

и писал он нечто вроде "попался неоконченный мультибайтовый символ", а не "попался неправильный символ", как обычно.

iconv (GNU libc) 2.3.2
 

Demiurg

Guest
что получаем ?
echo @iconv('utf8' , 'cp1251//ignore' , 'asdfgфhjkl');
 

DiTHER

bang bang
отчасти ты прав. я стормозил слегка
но правда при этом он пишет Detected an illegal character in input, а не Detected an incomplete multibyte character in input. Хотя впрочем это не мешает ему работать, действительно.

Все равно вариант не подходит - т.к. нотисы отключать не хочу (а если плюнуть то почта и лог на серве превращаются в груду металлолома). Anyway, thanks.

-~{}~ 28.06.05 13:17:

будем совершенствовать труда SiMM'а, напишу о результатах.
 

Demiurg

Guest
тебе не надо отключать нотисы везде ... тебе надо отключить нотиси только там, где они тее не нужны.
 

DiTHER

bang bang
Demiurg,

это вариант вида "повернуться и удрать от проблемы" :) Когда-нибудь все равно аукнется.. да и разобраться досканально с уникодом раз уж взялся тоже неплохо :)

И нотисы отключать, переписав обработчик ошибок слегка проблематично. :)

Спасибо за содействие
 
Сверху