2

MySQL は、一連の文字を 16 進数表現に変換する関数 HEX() を使用します。唯一の問題は、各文字が 2 バイトであると想定していることです。ほとんどの場合はこれで問題ありませんが、utf-8 では 2 バイトを超える文字が存在することがあります。

例えば。0xEFBFBD は、エンコード エラーを通知するために使用される 3 バイト文字です。DB (合計 6 バイト) の utf8 でエンコードされたテーブルにこれらの文字を 2 つ続けて配置し、SELECT HEX(col1) FROM テーブル ... を実行すると、0xEFBFBD ではなく 0xC3AFC2BFC2BD として出力されます。PHPでクエリを使用して選択し、PHP内で16進数に変換すると、正しい形式になります。

最適なのは、関数が適切なマルチバイト UTF8 をデコードできる MySql であることです。存在しないように見えることに非常に驚いています。他の誰かがこれに該当することを発見したかどうか、および可能な回避策があるかどうかを知りたいです。

MySql の回答に最も近いものは次のとおりです。 http://forums.mysql.com/read.php?103,375304,375660

しかし、このアドバイスは実際には役に立ちません。誰も頭から離れたアイデアがない場合は、後でテストケースを投稿します。

4

1 に答える 1

2

このHEX関数は、実際に格納されているバイトを返します。MySQLは文字エンコーディングの混合を喜んで保存することを忘れないでください。文字ごとに2バイトを取得する場合、値はucs2またはutf16でエンコードする必要があります。エンコーディングを確認するには、CHARSET関数を使用できます。

この特定のケースでは、列にUTF-16でエンコードされた쎯슿슽(U + C3AF U + C2BF U + C2BD)が含まれているようです。��(U + FFFD U + FFFD)が保存された値であると思わせる他の問題があるはずです。おそらく、PHPプログラムは、ucs2またはutf16接続文字セットとして、またはを使用していて、取得したテキストをUTF-8であるかのように扱いますか?


更新:文字列のUTF-8エンコーディングの16進表現(任意の文字列、任意のエンコーディング*)を取得するには、を使用しますHEX(CONVERT(string USING utf8))。例えば:

set @unknown = char(0xFFFD using ucs2);        -- stored bytes: \xFF \xFD
select hex(convert(@unknown using utf8));      -- output: EFBFBD

*)変換元のエンコーディングがないバイナリ文字列を除く

于 2012-07-15T11:33:21.590 に答える