web-dev-qa-db-ja.com

PHPで不正なutf-8文字列を検出する方法は?

iconv関数は時々エラーを出します:

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

データを変換する前に、utf-8文字列に不正な文字があることを検出する方法はありますか?

23
rsk82

まず、テキストが特定の望ましくないエンコーディングに属しているかどうかを検出できないことに注意してください。文字列が特定のエンコーディングで有効かどうかのみを確認できます。

preg_matchで利用できるUTF-8有効性チェックを利用できます。 [PHPマニュアル] 以来PHP 4.3.5。無効な文字列が指定された場合、追加情報なしで0を返します:

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

別の可能性は mb_check_encoding [PHPマニュアル]

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

使用できるもう1つの関数は 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マニュアルページの例も確認してください。

通知の原因となっているソースコードを共有していません。より具体的な提案が必要な場合は、追加する必要があります。

48
hakre

UTF-8で無効な文字の仕様はかなり明確です。おそらく、それを解析する前にそれらを取り除く必要があります。それらはそこにあるべきではないので、XMLを生成する前にそれを回避することができれば、さらに優れたものになるでしょう。

参照はこちらをご覧ください:

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

これは完全なリストではありません。多くのパーサーは、番号の小さい制御文字も許可していませんが、現時点では包括的なリストを見つけることができません。

ただし、iconvはこれを組み込みでサポートしている場合があります。

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

0
jishi

mb_detect_encoding(UTF-8以外の)別の文字セットがあるかどうかを検出するには、mb_convert_encoding必要に応じてUTF-8に変換します。無効なUTF-8を提供するよりも、別の文字セットで有効なコンテンツを提供している可能性が高くなります。

0
Robin

iconv()の前に@を付けてNOTICEを抑制し、ソースエンコーディングIDのUTF-8の後に// IGNOREを付けて無効な文字を無視します。

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