Как обнаружить неверную строку utf-8 в PHP?

Функция iconv иногда дает мне ошибку:

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

Есть ли способ обнаружить, что в строке utf-8 есть недопустимые символы, прежде чем помещать данные в inconv?

Ответ 1

Во-первых, обратите внимание, что невозможно определить, принадлежит ли текст конкретной нежелательной кодировке. Вы можете проверить, действительно ли строка в данной кодировке.

Вы можете использовать проверку действительности UTF-8, которая доступна в preg_match [Руководство PHP] с PHP 4.3.5. Он вернет 0 (без дополнительной информации), если указана недопустимая строка:

$isUTF8 = preg_match('//u', $string);

Другая возможность - mb_check_encoding [Руководство по PHP]:

$validUTF8 = mb_check_encoding($string, 'UTF-8');

Другая функция, которую вы можете использовать, - mb_detect_encoding [Руководство по PHP]:

$validUTF8 = ! (false === mb_detect_encoding($string, 'UTF-8', true));

Важно установить параметр strict на true.

Кроме того, iconv [Руководство PHP] позволяет вам изменять/отбрасывать недопустимые последовательности на летать. (Однако, если iconv встречает такую ​​последовательность, она генерирует уведомление, это поведение не может быть изменено.)

echo 'TRANSLIT : ', iconv("UTF-8", "ISO-8859-1//TRANSLIT", $string), PHP_EOL;
echo 'IGNORE   : ', iconv("UTF-8", "ISO-8859-1//IGNORE", $string), PHP_EOL;

Вы можете использовать @ и проверить длину возвращаемой строки:

strlen($string) === strlen(@iconv('UTF-8', 'UTF-8//IGNORE', $string));

Проверьте примеры на странице руководства iconv.

Вы не поделились исходным кодом, из которого возникает уведомление. Вы должны добавить его, если хотите более конкретное предложение.

Ответ 2

Спецификация символов, недопустимых в UTF-8, довольно ясна. Вы, вероятно, захотите снять их, прежде чем пытаться его разобрать. Их не должно быть так, чтобы вы могли избежать этого даже до создания XML, который был бы еще лучше.

См. здесь ссылку:

http://www.w3.org/TR/xml/#charsets

Это не полный список, многие парсер также запрещают некоторые низкоуровневые управляющие символы, но сейчас я не могу найти исчерпывающий список.

Однако iconv может иметь встроенную поддержку для этого:

http://www.zeitoun.net/articles/clear-invalid-utf8/start

Ответ 3

Вы можете попробовать использовать mb_detect_encoding, чтобы определить, есть ли у вас другой набор символов (чем UTF-8), а затем mb_convert_encoding для преобразования в UTF-8, если это необходимо. Вероятнее всего, что люди дают вам действительный контент в другом наборе символов, чем предоставление недопустимого UTF-8.

Ответ 4

поставьте @перед iconv(), чтобы подавить NOTICE и //IGNORE после UTF-8 в идентификаторе исходного кода, чтобы игнорировать недопустимые символы:

@iconv( 'UTF-8//IGNORE', $destinationEncoding, $yourString );