PHP - 带有'SORT_LOCALE_STRING'的排序函数返回错误的结果

时间:2017-07-31 15:33:36

标签: php mysql collation


我在 VARCHAR 类型中有一些MySQL记录,排序规则是 utf8mb4_unicode_ci

Tiếng Việt Nam
Tiếng Hoa Kỳ
Tiếng Anh
Tiếng Nhật
Tiếng Hàn Quốc
Tiếng Thái Lan

然后,我使用PHP按字母顺序对它们进行排序:

$languages = [
        'Tiếng Việt Nam',
        'Tiếng Hoa Kỳ',
        'Tiếng Anh',
        'Tiếng Nhật',
        'Tiếng Hàn Quốc',
        'Tiếng Thái Lan',
    ];
setlocale(LC_COLLATE, 'vi');
sort($languages, SORT_LOCALE_STRING);

调用var_dump($languages)时的结果:

array (size=6)
  0 => string 'Tiếng Anh' (length=11)
  1 => string 'Tiếng Hoa Kỳ' (length=16)
  2 => string 'Tiếng Nhật' (length=14)
  3 => string 'Tiếng Thái Lan' (length=17)
  4 => string 'Tiếng Việt Nam' (length=18)
  5 => string 'Tiếng Hàn Quốc' (length=22)

'TiếngHànQuốc'的顺序错误,结果应如下:

array (size=6)
  0 => string 'Tiếng Anh' (length=11)
  1 => string 'Tiếng Hàn Quốc' (length=19)
  2 => string 'Tiếng Hoa Kỳ' (length=16)
  3 => string 'Tiếng Nhật' (length=14)
  4 => string 'Tiếng Thái Lan' (length=17)
  5 => string 'Tiếng Việt Nam' (length=18)

然后,我通过直接输入MySQL(使用HeidiSQL)替换已存在的'TiếngHànQuốc'与其他人(也是'TiếngHànQuốc')。最后,我得到了预期的结果。

我认为这里的不同之处是:

string 'Tiếng Hàn Quốc'(length=22)
string 'Tiếng Hàn Quốc'(length=19)

问题是: 什么是问题的根源? 如何在MySql或PHP代码中解决此问题以获得预期结果而无需查找并替换MySQL中的所有不正确的值?

谢谢。

1 个答案:

答案 0 :(得分:0)

简短回答:您需要这种整理:utf8mb4_vietnamese_ci

答案很长:字符串具有不同的UTF-8十六进制表示:

Tiếng Hàn Quốc (length=20)  54 69 C3AA CC81 6E 67 48 61 CC80 6E 51 75 C3B4 CC81 63
Tiếng Hàn Quốc (length=17)  54 69  E1BABF   6E 67 48  C3A0   6E 51 75  E1BB91   63

然而,存在一个潜在的问题:

C3AA        234=x00EA  [ê]    L  LATIN SMALL LETTER E WITH CIRCUMFLEX
CC81        769=x0301  [́]  NSM  COMBINING ACUTE ACCENT
6E          110=x006E  [n]    L  LATIN SMALL LETTER N

E1BABF     7871=x1EBF  [ế]    L  LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
6E          110=x006E  [n]    L  LATIN SMALL LETTER N

在第一个字符串中,ê通过单个utf8字符(十六进制C3AA)呈现,而acute-n通过一对utf8字符呈现 - 非间距重音和字母n。

在第一个字符串中,尖锐的重音是字母e的一部分。我对utf8中的越南语编码一无所知,但如果急性信号确实应该出现在字母n上,这听起来是“错误的”。

但是,无论如何,这两个字符串与collat​​ion utf8mb4_vietnamese_ci(或utf8_vietnamese_ci)相等。