Проверьте правильность кодирования строки с помощью функций PHP intl (ICU) - PullRequest
0 голосов
/ 08 июля 2011

Используя функции, доступные в настоящее время в оболочке PHP intl для ICU, как вы будете проверять правильность кодировки строки?(например, проверьте действительный UTF-8)

Я знаю, что это можно сделать с помощью mbstring, iconv () и PCRE, но меня особенно интересует intl с этим вопросом.

Ответы [ 2 ]

2 голосов
/ 31 мая 2013

UConverter можно использовать начиная с PHP 5.5. Руководство не существует. См. https://wiki.php.net/rfc/uconverter для API.

function replace_invalid_byte_sequence($str)
{
    return UConverter::transcode($str, 'UTF-8', 'UTF-8');
}

function replace_invalid_byte_sequence2($str)
{
    return (new UConverter('UTF-8', 'UTF-8'))->convert($str);
}

function utf8_check_encoding($str)
{
    return $str === UConverter::transcode($str, 'UTF-8', 'UTF-8');
}

function utf8_check_encoding2($str)
{
    return $str === (new UConverter('UTF-8', 'UTF-8'))->convert($str);
}

// Table 3-8. Use of U+FFFD in UTF-8 Conversion
// http://www.unicode.org/versions/Unicode6.1.0/ch03.pdf)
$str =  "\x61"."\xF1\x80\x80"."\xE1\x80"."\xC2"."\x62"."\x80"."\x63"
    ."\x80"."\xBF"."\x64";
$expected = 'a���b�c��d';

var_dump([
    $expected === replace_invalid_byte_sequence($str),
    $expected === replace_invalid_byte_sequence2($str)
],[
    false === utf8_check_encoding($str),
    false === utf8_check_encoding2($str)
]);
0 голосов
/ 10 июля 2011

Я немного покопался и нашел ICU unorm2_normalize () документацию .Его параметр pErrorCode out интересен.Стандартные коды ошибок ICU начинаются около строки 620 utypes.h .Итак, я попробовал этот тестовый скрипт:

$s = 'tête-à-tête';
echo "normalizer_normalize(\$s) >> " 
     . var_export(normalizer_normalize($s), 1) . "\n";
$s = "\xFF" . $s;
echo "normalizer_normalize(\$s) >> " 
     . var_export($r=normalizer_normalize($s), 1) . "\n";
if ($r===false)
    echo "normalizer_normalize() error: " 
         . intl_get_error_message() . "\n";
// which outputs:
normalizer_normalize($s) >> 'tête-à-tête'
normalizer_normalize($s) >> false
normalizer_normalize() error: Error converting input string to UTF-16: U_INVALID_CHAR_FOUND

Итак, я думаю, что тест, основанный на этом и поиск следующих трех кодов ошибок, будет приличным признаком плохой кодировки UTF-8:

U_INVALID_CHAR_FOUND Преобразование символов: не отображаемая последовательность ввода.U_TRUNCATED_CHAR_FOUND Преобразование символов: неполная последовательность ввода.U_ILLEGAL_CHAR_FOUND Преобразование символов: Неверная последовательность ввода / комбинация единиц ввода.

Или, когда мне лень, я могу просто использовать

normalizer_normalize($s)===false

Кстати: я смущенстрока спецификации API ICU:

pErrorCode Стандартный код ошибки ICU.Его входное значение должно пройти тест U_SUCCESS (), иначе функция вернется немедленно.Проверьте U_FAILURE () на выходе или используйте с функциональной цепочкой.(Подробнее см. В Руководстве пользователя.)

Фраза "функция немедленно возвращается" стимулирует выполнение моего теста, но относится ли "функция" к unorm2_normalize () или U_SUCCESS ()?Есть идеи?

...