2

utf8mb4 文字を含む JSON 文字列があります。最初に JSON を解析し、次に結果をエンコードして JSON に戻します。その後、結果の JSON を mysql データベースに保存します。(これは単純化された実行フローです。最初に JSON を解析してからエンコードし直すのには実際の理由があります)。

問題は、データベースが、そこに配置した JSON 文字列のプレフィックスで終わり、最初の utf8mb4 文字で切り取られることです。

これが私のコードです:

require 'json'
require 'mysql2'

TABLENAME = 'my_table'

settings = {
  :database => "my_database",
  :host => "localhost",
  :password => "my_password",
  :username => "my_username"
}

@database = Mysql2::Client.new settings
@json = %q({"test":"begin \ud83d\ude04\ud83d\udc4d\ud83d\udc4f\ud83d\udd14 end"})

begin
  obj = JSON.parse @json
rescue JSON::ParserError => e
  @json.force_encoding 'utf-8'
  encoded = @json.valid_encoding? ? @json : @json.encode!('utf-8', invalid: :replace, undef: :replace)
  obj = JSON.parse encoded
end

q = "create table if not exists `#{TABLENAME}` (json text not null) engine=InnoDB default charset=utf8"
@database.query q

text = @database.escape JSON.generate obj
q = "insert ignore into `#{TABLENAME}` (json) values('#{text}')"
@database.query q

q = "select * from `#{TABLENAME}`"
rs = @database.query q

rs.each {|r|
  p r
}

出力は次のとおりです。

{"json"=>"{\"test\":\"begin "}

なぜこれが起こるのかわかりません。助けていただければ幸いです。

4

1 に答える 1

2

これを修正する方法を見つけるのを手伝ってくれた @muistooshort に感謝します。

...
settings = {
  ...
  :encoding => 'utf8mb4'
}
...
q = "create table ... default charset=utf8mb4"
...

もちろん、これは utf8mb4 をサポートするエンジンでのみ機能します。

于 2013-04-05T03:35:48.857 に答える