MySQL,UTF-8和Emoji字符

我正在开发一个带有PHP + MySQL后端的iOS应用程序。 该应用程序有一个聊天部分,需要支持表情符号。 我的表是utf8_unicode_ci。 如果我不在脚本中调用“设置名称utf8”,表情符号实际上可以工作 – 无论input到数据库中,它都会返回给客户端。

问题是这(如果我理解正确)在数据库中不正确地存储特殊字符,这打破了string比较(即比较string时,我不再是相同的)。

但是,如果我打电话给名字utf8,突然间插入表情符号作为一堆问号。

任何build议在正确的方式处理这个? 谢谢!

问题是db有一个变音敏感的比较。 另一个问题是组成字符,ï可以表示为一个unicode字符或两个形成代理对。 有一些方法可以将string转换为预先组合或分解的forms:precomposedStringWith *和decomposedStringWith *。

看来MySQL支持两种forms的unicode ucs2(这是一种由utf16取代的旧forms),每种字符16位,utf8每种字符最多3个字节。 坏消息是,这两种forms都不支持17位的平面1字符。 (主要是表情符号)。 它看起来像MySQL 5.5.3,最多也支持utf8mb4,utf16和utf32支持BMP和补充字符(阅读表情符号)。 请参阅MySQL Unicode字符集 。

下面是一些代码和结果来演示不同的Unicode字节表示。
Unicode是一个21位编码系统。
UTF32直接表示代码点,并清楚地演示了分解代理对。
UTF8和UTF16需要一个或多个字节来表示一个Unicode字符。

NSLog(@"character: %@", @"Å"); NSLog(@"decomposedStringWithCanonicalMapping UTF8: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF8StringEncoding]); NSLog(@"decomposedStringWithCanonicalMapping UTF16: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF16BigEndianStringEncoding]); NSLog(@"decomposedStringWithCanonicalMapping UTF32: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF32BigEndianStringEncoding]); NSLog(@"precomposedStringWithCanonicalMapping UTF8: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF8StringEncoding]); NSLog(@"precomposedStringWithCanonicalMapping UTF16: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF16BigEndianStringEncoding]); NSLog(@"precomposedStringWithCanonicalMapping UTF32: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF32BigEndianStringEncoding]); NSLog(@"character: %@", @"😱"); NSLog(@"dataUsingEncoding UTF8: %@", [@"😱" dataUsingEncoding:NSUTF8StringEncoding]); NSLog(@"dataUsingEncoding UTF16: %@", [@"😱" dataUsingEncoding:NSUTF16BigEndianStringEncoding]); NSLog(@"dataUsingEncoding UTF32: %@", [@"😱" dataUsingEncoding:NSUTF32BigEndianStringEncoding]); 

//对于一些代理对来说,没有其他的forms

 NSString *aReverse = [[NSString alloc] initWithBytes:"\xD8\x3C\xDD\x70\x00" length:4 encoding:NSUTF16BigEndianStringEncoding]; NSLog(@"character: %@", aReverse); NSLog(@"dataUsingEncoding UTF8: %@", [aReverse dataUsingEncoding:NSUTF8StringEncoding]); NSLog(@"dataUsingEncoding UTF16: %@", [aReverse dataUsingEncoding:NSUTF16BigEndianStringEncoding]); NSLog(@"dataUsingEncoding UTF32: %@", [aReverse dataUsingEncoding:NSUTF32BigEndianStringEncoding]); 

NSLog输出:

 character: Å decomposedStringWithCanonicalMapping UTF8: <41cc8a> decomposedStringWithCanonicalMapping UTF16: <0041030a> decomposedStringWithCanonicalMapping UTF32: <00000041 0000030a> precomposedStringWithCanonicalMapping UTF8: <c385> precomposedStringWithCanonicalMapping UTF16: <00c5> precomposedStringWithCanonicalMapping UTF32: <000000c5> character: 😱 dataUsingEncoding UTF8: <f09f98b1> dataUsingEncoding UTF16: <d83dde31> dataUsingEncoding UTF32: <0001f631> character: 🅰 dataUsingEncoding UTF8: <f09f85b0> dataUsingEncoding UTF16: <d83cdd70> dataUsingEncoding UTF32: <0001f170>