2011-07-08 9 views
0

現在、PHPのintl ICUのラッパーで使用できる機能を使用して、文字列のエンコーディングの有効性をチェックする方法はありますか? (有効なUTF-8を確認するなど)PHPのintl(ICU)機能で有効な文字列のエンコーディングを確認する

mbstring、iconv()、PCREを使用することができますが、私はこの質問でintlに特に関心があります。

+0

あなたはUCS4に変換して戻ってエラーが発生するかどうかを確認できます。有効なUTF8をお持ちの場合、これは完全に可逆的な手順です。これはおそらく*最速*の解決策ではありませんが、メガバイトのデータをチェックしていない限り、問題はないはずです。 –

+0

私はそれがうまくいくと思います。しかし、それはintlのどの部分ですか? http://php.net/manual/en/book.intl.php –

答えて

0

掘り出しを行ったところ、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を参照してくださいでしょうか?何か案は?

+0

http://userguide.icu-project.org/design#TOC-Error-Handlingを参照してください.-基本的に、エラーコードが既に失敗している場合機能はちょうど戻って、何らかの(もっと)仕事をしようとしません。 PHPのラッパーは、ICU関数を呼び出すたびにエラー値をリセットする必要があります。ここで、「関数」とはU_SUCCESS()ではなく、normalize()を指します。 –

2

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) 
]); 
関連する問題