Как обнаружить искаженную строку utf-8 в PHP?
Функция iconv иногда выдает мне ошибку:
Notice:
iconv() [function.iconv]:
Detected an incomplete multibyte character in input string in [...]
Есть ли способ обнаружить, что в строке utf-8 есть недопустимые символы, прежде чем помещать данные в inconv?
5 ответов
Во-первых, обратите внимание, что невозможно определить, принадлежит ли текст к определенной нежелательной кодировке. Вы можете проверить только допустимость строки в данной кодировке.
Вы можете использовать проверку достоверности 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
страница руководства также.
Вы не передали исходный код, из которого получено уведомление. Вы должны добавить его, если хотите более конкретное предложение.
Для использования json_encode попробуйте json_last_error
<?php
// An invalid UTF8 sequence
$text = "\xB1\x31";
$json = json_encode($text);
$error = json_last_error();
var_dump($json, $error === JSON_ERROR_UTF8);
вывод (например, для версий PHP 5.3.3–5.3.13, 5.3.15–5.3.29, 5.4.0–5.4.45)
string(4) "null"
bool(true)
Вы можете попробовать использовать mb_detect_encoding
чтобы определить, есть ли у вас другой набор символов (чем UTF-8), тогда mb_convert_encoding
преобразовать в UTF-8, если требуется. Скорее всего, люди дают вам действительный контент в другом наборе символов, чем недействительный UTF-8.
Поставить @ перед iconv() для подавления NOTICE и //IGNORE после UTF-8 в идентификаторе кодировки источника, чтобы игнорировать недопустимые символы:
@iconv( 'UTF-8//IGNORE', $destinationEncoding, $yourString );
Спецификация символов недопустимых символов в UTF-8 довольно ясна. Вы, вероятно, хотите раздеть их, прежде чем пытаться разобрать его. Их не должно быть, поэтому, если бы вы могли избежать этого даже до генерации XML, это было бы еще лучше.
Смотрите здесь для справки:
Это не полный список, многие парсеры также запрещают использование некоторых управляющих символов с низким номером, но я не могу найти полный список прямо сейчас.
Тем не менее, iconv может иметь встроенную поддержку для этого: