現在、PHPのintl ICUのラッパーで使用できる機能を使用して、文字列のエンコーディングの有効性をチェックする方法はありますか? (有効なUTF-8を確認するなど)PHPのintl(ICU)機能で有効な文字列のエンコーディングを確認する
mbstring、iconv()、PCREを使用することができますが、私はこの質問でintlに特に関心があります。
現在、PHPのintl ICUのラッパーで使用できる機能を使用して、文字列のエンコーディングの有効性をチェックする方法はありますか? (有効なUTF-8を確認するなど)PHPのintl(ICU)機能で有効な文字列のエンコーディングを確認する
mbstring、iconv()、PCREを使用することができますが、私はこの質問でintlに特に関心があります。
掘り出しを行ったところ、ICU unorm2_normalize() documentationが見つかりました。そのpErrorCode出力パラメータは面白いです。標準的なICUエラーコードは、utypes.hの620行目から始まります。だから私は、このテストスクリプトを試してみました:
$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
だから私はテストそれに基づいて、次の3つのエラー・コードを探しているが、悪いUTF-8エンコーディングのまともな表示になります推測:
U_INVALID_CHAR_FOUNDキャラクター変換:マッピング不可能な入力シーケンス。 U_TRUNCATED_CHAR_FOUND文字変換:入力シーケンスが不完全です。 U_ILLEGAL_CHAR_FOUND文字変換:不正な入力シーケンス/入力ユニットの組み合わせ。
それとも私が怠惰な感じているとき、私はちょうどところで
normalizer_normalize($s)===false
を使用することができます。私は困惑しているICUのAPI仕様のこの行で:
pErrorCode標準ICUエラーコード。 入力値は U_SUCCESS()テストに合格する必要があります。それ以外の場合は、すぐに関数 が戻ります。出力には U_FAILURE()をチェックするか、 関数連鎖で使用してください。 ( 詳細については、ユーザガイドを参照してください。)
「機能はすぐに戻ります」というフレーズは、私のテストの再性能を奨励しているが、「機能」()またはU_SUCCESS()をunorm2_normalizeを参照してくださいでしょうか?何か案は?
http://userguide.icu-project.org/design#TOC-Error-Handlingを参照してください.-基本的に、エラーコードが既に失敗している場合機能はちょうど戻って、何らかの(もっと)仕事をしようとしません。 PHPのラッパーは、ICU関数を呼び出すたびにエラー値をリセットする必要があります。ここで、「関数」とはU_SUCCESS()ではなく、normalize()を指します。 –
UConverterはPHP 5.5以降で使用できます。マニュアルは存在しません。 APIについてはhttps://wiki.php.net/rfc/uconverterを参照してください。
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)
]);
あなたはUCS4に変換して戻ってエラーが発生するかどうかを確認できます。有効なUTF8をお持ちの場合、これは完全に可逆的な手順です。これはおそらく*最速*の解決策ではありませんが、メガバイトのデータをチェックしていない限り、問題はないはずです。 –
私はそれがうまくいくと思います。しかし、それはintlのどの部分ですか? http://php.net/manual/en/book.intl.php –