php - MySQL、UTF-8 和 Emoji 字符

标签 php mysql ios utf-8 emoji

我正在开发一个带有 PHP+MySQL 后端的 iOS 应用程序。该应用程序有一个聊天部分,需要支持表情符号。 我的表是 utf8_unicode_ci。如果我不在我的脚本中调用“set names utf8”,表情符号实际上会起作用——无论输入数据库的是什么,都会按原样返回给客户。

问题是这(如果我理解正确的话)在数据库中错误地存储了特殊字符,这会破坏字符串比较(即在比较字符串时 ï 不再与 i 相同)。

但是,如果我调用 set names utf8,表情符号字符会突然插入为一串问号。

关于正确处理这个问题的任何建议?谢谢!

最佳答案

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

似乎 MySQL 支持两种形式的 unicode ucs2(这是一种被 utf16 取代的旧形式),即每个字符 16 位和 utf8 每个字符最多 3 个字节。坏消息是这两种形式都不支持需要 17 位的平面 1 字符。 (主要是表情符号)。看起来 MySQL 5.5.3 及更高版本还支持 utf8mb4、utf16 和 utf32,支持 BMP 和增补字符(阅读表情符号)。参见 MySQL Unicode Character Sets .

这里有一些代码和结果来演示不同的 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]);

//对于一些代理对没有其他形式

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>

关于php - MySQL、UTF-8 和 Emoji 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24253985/

相关文章:

php - 在 Drupal 中自定义 WebForm 模块

javascript - 将自定义字段用于 braintree 的托管字段和插入

ios - 启动 EASession 失败——EAAccessory 没有协议(protocol)

ios - swift iOS - UICollectionView 图像在快速滚动后混淆

PHP 通过 id 而不是 name 更新 MySQL

使用 Wamp 服务器在 WordPress 上运行 PHP

mysql - 按两列 mysql 分组的列计数总和

mysql - 使用左连接限制查询

mysql - 在 Hadoop 2.6.0 中执行 Sqoop import 命令时遇到问题

ios - 将数组中的项目从最近到最公平排序(从我的位置开始)