PHP,MySQL中带有utf8数据的奇怪排序问题 [英] Strange sorting problem in PHP, mysql with utf8 data

查看:82
本文介绍了PHP,MySQL中带有utf8数据的奇怪排序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个数据库表有一个非常奇怪的问题.我将各个区域归类为区域(区域A,区域B等),当我运行查询以在下拉菜单中显示它们时,我得到了

I have a very strange problem with one of my db tables. I have various areas categorized in zones (Zone A, Zone B etc) and when I run a query to display them in a dropdown menu i get

  • A区-K区
  • A区-L区
  • A区-M区
  • A区-N区
  • A区-O区
  • A区-P区
  • A区-A区
  • A区-B区
  • A区-C区
  • A区-D区
  • ...
  • A区-G区
  • B区-K区
  • B区-L区
  • B区-M区
  • B区-N区
  • B区-O区
  • B区-P区
  • B区-A区
  • B区-B区
  • B区-C区
  • B区-D区
  • Zone A - Area K
  • Zone A - Area L
  • Zone A - Area M
  • Zone A - Area N
  • Zone A - Area O
  • Zone A - Area P
  • Zone A - Area A
  • Zone A - Area B
  • Zone A - Area C
  • Zone A - Area D
  • ...
  • Zone A - Area G
  • Zone B - Area K
  • Zone B - Area L
  • Zone B - Area M
  • Zone B - Area N
  • Zone B - Area O
  • Zone B - Area P
  • Zone B - Area A
  • Zone B - Area B
  • Zone B - Area C
  • Zone B - Area D

出于某些奇怪的原因,区域从K-> Z开始显示,然后从A开始.

For some strange reason the areas are being displayed from K->Z and then starts from A.

我的表的结构如下:CREATE TABLE区域(id int(11)NOT NULL AUTO_INCREMENT,区域varchar(20)DEFAULT NULL,区域varchar(100)NOT NULL,距离float(9,2)DEFAULT NULL,PRIMARY KEY(id))ENGINE = MyISAM DEFAULT CHARSET = utf8;

My table's structure is as follows: CREATE TABLE areas ( id int(11) NOT NULL AUTO_INCREMENT, zone varchar(20) DEFAULT NULL, area varchar(100) NOT NULL, distance float(9,2) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

我表中的数据是希腊文,我仅作了上面的示例,因此您可以理解并看到问题所在.要查看实际数据(希腊文),您可以访问 http://www.emanaviko.gr/lists/suburbs.php

The data in my table is in Greek, I made the above example only so you could understand and see the problem. To view the actual data (in Greek) you can visit http://www.emanaviko.gr/lists/suburbs.php

推荐答案

我已将您的数据导入到表中,它似乎与您得到的排序有所不同.您的默认排序规则是什么?我的是utf8_general_ci.

I've imported your data into a table and it seems to sort different from what you get. What is your default collation ? Mine is utf8_general_ci.

请注意,实际上,即使您是西式字母也不是西式字母.例如,您的K实际上是Unicode字符"GREEK CAPITAL LETTER KAPPA".

Note that even your western-looking letters are, in fact, not western letters. For instance, your K is in fact the unicode character "GREEK CAPITAL LETTER KAPPA".

mysql> show create table foo;

+-------+----------------------------------------------------------------------------------+
| Table | Create Table                                                                     |
+-------+----------------------------------------------------------------------------------+
| foo   | CREATE TABLE `foo` (
  `z` text,
  `a` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------+

mysql> select * from foo order by z,a collate utf8_general_ci;
+-------------+-------------------------------------------------+
| z           | a                                               |
+-------------+-------------------------------------------------+
| ΖΩΝΗ Α | Αγία Βαρβάρα                         |
| ΖΩΝΗ Α | Αγία Παρασκευή                     |
| ΖΩΝΗ Α | Αγιοι Ανάργυροι                   |
| ΖΩΝΗ Α | Αγιος Στέφανος                     |
| ΖΩΝΗ Α | Αιγάλεω                                  |
| ΖΩΝΗ Α | Ανθούσα                                  |
| ΖΩΝΗ Α | Ανοιξη                                    |
| ΖΩΝΗ Α | Ανω Λιόσια                             |
| ΖΩΝΗ Α | Αχαρνές (Μενίδι)                   |
| ΖΩΝΗ Α | Βριλήσσια                              |
| ΖΩΝΗ Α | Γαλάτσι                                  |
| ΖΩΝΗ Α | Γέρακας                                  |
| ΖΩΝΗ Α | Γλυκά Νερά                             |
| ΖΩΝΗ Α | Διόνυσος                                |
| ΖΩΝΗ Α | Δροσιά                                    |
| ΖΩΝΗ Α | Εκάλη                                      |
| ΖΩΝΗ Α | Ζεφύρι                                    |
| ΖΩΝΗ Α | Ηράκλειο                                |
| ΖΩΝΗ Α | Θρακομακεδόνες                    |
| ΖΩΝΗ Α | Ιλιον                                      |
| ΖΩΝΗ Α | Κηφισιά                                  |
| ΖΩΝΗ Α | Κρυονέρι                                |
| ΖΩΝΗ Α | Λυκόβρυση                              |
| ΖΩΝΗ Α | Μαρούσι                                  |
| ΖΩΝΗ Α | Μελίσσια                                |
| ΖΩΝΗ Α | Νέα Ερυθραία                         |
| ΖΩΝΗ Α | Παλλήνη                                  |
| ΖΩΝΗ Α | Παπάγου                                  |
| ΖΩΝΗ Α | Πεντέλη                                  |
| ΖΩΝΗ Α | Περιστέρι                              |
| ΖΩΝΗ Α | Πετρούπολη                            |
| ΖΩΝΗ Α | Πεύκη                                      |
| ΖΩΝΗ Α | Ροδόπολη                                |
| ΖΩΝΗ Α | Σταμάτα                                  |
| ΖΩΝΗ Α | Φιλοθέη                                  |
| ΖΩΝΗ Α | Χαϊδάρι                                  |
| ΖΩΝΗ Α | Χαλάνδρι                                |
| ΖΩΝΗ Α | Χαλκηδόνα                              |
| ΖΩΝΗ Α | Χολαργός                                |
| ΖΩΝΗ Α | Ψυχικό                                    |
| ΖΩΝΗ Β | Αγία Σοφία                             |
| ΖΩΝΗ Β | Αγιος Βασίλειος                   |
| ΖΩΝΗ Β | Αγιος Δημήτριος(Μπραχάμι) |
| ΖΩΝΗ Β | Αλιμος                                    |
| ΖΩΝΗ Β | Ανω Γλυφάδα                           |
| ΖΩΝΗ Β | Αργυρούπολη                          |
| ΖΩΝΗ Β | Βάρη                                        |
| ΖΩΝΗ Β | Βάρκιζα                                  |
| ΖΩΝΗ Β | Βούλα                                      |
| ΖΩΝΗ Β | Βουλιαγμένη                          |
| ΖΩΝΗ Β | Βύρωνας                                  |
| ΖΩΝΗ Β | Γλυφάδα                                  |
| ΖΩΝΗ Β | Δάφνη                                      |
| ΖΩΝΗ Β | Ελληνικό                                |
| ΖΩΝΗ Β | Ζωγράφου                                |
| ΖΩΝΗ Β | Ηλιούπολη                              |
| ΖΩΝΗ Β | Καβούρι                                  |
| ΖΩΝΗ Β | Καισαριανή                            |
| ΖΩΝΗ Β | Καλλιθέα                                |
| ΖΩΝΗ Β | Καλλίπολη                              |
| ΖΩΝΗ Β | Καμίνια                                  |
| ΖΩΝΗ Β | Καστέλα                                  |
| ΖΩΝΗ Β | Νέα Σμύρνη                             |
| ΖΩΝΗ Β | Παλαιό Φάληρο                       |
| ΖΩΝΗ Β | Υμηττός                                  |
+-------------+-------------------------------------------------+
65 rows in set (0.00 sec)

mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from foo order by z,a collate utf8_general_ci;
+-------------+-------------------------------------------------+
| z           | a                                               |
+-------------+-------------------------------------------------+
| ΖΩΝΗ Α | Αγία Βαρβάρα                         |
| ΖΩΝΗ Α | Αγία Παρασκευή                     |
| ΖΩΝΗ Α | Αγιοι Ανάργυροι                   |
| ΖΩΝΗ Α | Αγιος Στέφανος                     |
| ΖΩΝΗ Α | Αιγάλεω                                  |
| ΖΩΝΗ Α | Ανθούσα                                  |
| ΖΩΝΗ Α | Ανοιξη                                    |
| ΖΩΝΗ Α | Ανω Λιόσια                             |
| ΖΩΝΗ Α | Αχαρνές (Μενίδι)                   |
| ΖΩΝΗ Α | Βριλήσσια                              |
| ΖΩΝΗ Α | Γαλάτσι                                  |
| ΖΩΝΗ Α | Γέρακας                                  |
| ΖΩΝΗ Α | Γλυκά Νερά                             |
| ΖΩΝΗ Α | Διόνυσος                                |
| ΖΩΝΗ Α | Δροσιά                                    |
| ΖΩΝΗ Α | Εκάλη                                      |
| ΖΩΝΗ Α | Ζεφύρι                                    |
| ΖΩΝΗ Α | Ηράκλειο                                |
| ΖΩΝΗ Α | Θρακομακεδόνες                    |
| ΖΩΝΗ Α | Ιλιον                                      |
| ΖΩΝΗ Α | Κηφισιά                                  |
| ΖΩΝΗ Α | Κρυονέρι                                |
| ΖΩΝΗ Α | Λυκόβρυση                              |
| ΖΩΝΗ Α | Μαρούσι                                  |
| ΖΩΝΗ Α | Μελίσσια                                |
| ΖΩΝΗ Α | Νέα Ερυθραία                         |
| ΖΩΝΗ Α | Παλλήνη                                  |
| ΖΩΝΗ Α | Παπάγου                                  |
| ΖΩΝΗ Α | Πεντέλη                                  |
| ΖΩΝΗ Α | Περιστέρι                              |
| ΖΩΝΗ Α | Πετρούπολη                            |
| ΖΩΝΗ Α | Πεύκη                                      |
| ΖΩΝΗ Α | Ροδόπολη                                |
| ΖΩΝΗ Α | Σταμάτα                                  |
| ΖΩΝΗ Α | Φιλοθέη                                  |
| ΖΩΝΗ Α | Χαϊδάρι                                  |
| ΖΩΝΗ Α | Χαλάνδρι                                |
| ΖΩΝΗ Α | Χαλκηδόνα                              |
| ΖΩΝΗ Α | Χολαργός                                |
| ΖΩΝΗ Α | Ψυχικό                                    |
| ΖΩΝΗ Β | Αγία Σοφία                             |
| ΖΩΝΗ Β | Αγιος Βασίλειος                   |
| ΖΩΝΗ Β | Αγιος Δημήτριος(Μπραχάμι) |
| ΖΩΝΗ Β | Αλιμος                                    |
| ΖΩΝΗ Β | Ανω Γλυφάδα                           |
| ΖΩΝΗ Β | Αργυρούπολη                          |
| ΖΩΝΗ Β | Βάρη                                        |
| ΖΩΝΗ Β | Βάρκιζα                                  |
| ΖΩΝΗ Β | Βούλα                                      |
| ΖΩΝΗ Β | Βουλιαγμένη                          |
| ΖΩΝΗ Β | Βύρωνας                                  |
| ΖΩΝΗ Β | Γλυφάδα                                  |
| ΖΩΝΗ Β | Δάφνη                                      |
| ΖΩΝΗ Β | Ελληνικό                                |
| ΖΩΝΗ Β | Ζωγράφου                                |
| ΖΩΝΗ Β | Ηλιούπολη                              |
| ΖΩΝΗ Β | Καβούρι                                  |
| ΖΩΝΗ Β | Καισαριανή                            |
| ΖΩΝΗ Β | Καλλιθέα                                |
| ΖΩΝΗ Β | Καλλίπολη                              |
| ΖΩΝΗ Β | Καμίνια                                  |
| ΖΩΝΗ Β | Καστέλα                                  |
| ΖΩΝΗ Β | Νέα Σμύρνη                             |
| ΖΩΝΗ Β | Παλαιό Φάληρο                       |
| ΖΩΝΗ Β | Υμηττός                                  |
+-------------+-------------------------------------------------+

更新:

好.我导入了您的转储文件.

OK. I imported your dump file.

您的问题是表格包含错误的数据.实际上是双重编码的utf8.

Your problem is that the tables contain the wrong data. It is in fact double-encoded utf8.

使用phpmyadmin查看表:您应该看到垃圾而不是文本.

Look into the tables using phpmyadmin : you should see garbage instead of text.

您的PHP代码中可能存在一个错误,您忘记发布"SET NAMES utf8"或mysql_set_charset("utf8").而且插入时您也遇到了同样的错误.

You probably have a bug in your PHP code, that you forgot to issue a "SET NAMES utf8" or a mysql_set_charset("utf8"). And you had the same bug when inserting.

因此,当您发出

INSERT 'Αγία Παρασκευή'

PHP将utf-8编码的数据发送到MySQL.但是MySQL认为它是latin1.因此,它将再次将其转换为utf8,并且您的表中包含垃圾.

PHP sends utf-8 encoded data to MySQL. But MySQL believes it is latin1. So, it converts it again to utf8, and your table contains garbage.

当您进行SELECT时,mysql会将utf8转换回latin1,但这实际上为您提供了最初发送的utf8,因此它可以正确显示在您的应用程序中.

When you SELECT, mysql converts utf8 back to latin1, but this actually gives you the utf8 you sent originally, so it displays correctly in your application.

但是表的内容是垃圾,并按垃圾顺序排序;)

But the contents of the tables are garbage, and sort in garbage order ;)

首先,您需要在代码中修复该错误.

First you need to fix that bug in your code.

然后,您需要导出这些表(提供的文件效果很好),将其删除,然后使用正确的字符集重新导入它们(在文件顶部添加一个SET NAMES utf8).

Then you need to export those tables (the file you gave works fine), drop them, and re-import them using the correct charset (add a SET NAMES utf8 at the top of the file).

更新2:

如果您想知道数据是否不是垃圾,有一些简单的技巧:

If you want to know if the data isn't garbage, there are simple tricks :

SELECT upper(yourcolumn) (or lower()...) 
SELECT char_length(yourcolumn)

如果它有效(即,您获得了正确的大写或小写文本以及正确的字符长度,则表明数据是正确的,并且mysql能够理解.

If it works (ie, you get the right uppercase or lowercase text and the right length in characters, then it means the data is good and mysql understands it.

检查您的mysql连接是否正确配置的常见技巧是发出(在您的php代码中)此查询:

Common trick to check if your mysql connection is properly configured is to issue (in your php code) this query :

SELECT char_length('é'), octet_length('é'), upper('é')
+-------------------+--------------------+-------------+
| char_length('é') | octet_length('é') | upper('é') |
+-------------------+--------------------+-------------+
|                 1 |                  2 | É          |
+-------------------+--------------------+-------------+

您当然可以

SHOW VARIABLES LIKE '%character%';

我使用phpmyadmin和mysql控制台.

I use phpmyadmin and the mysql console.

这篇关于PHP,MySQL中带有utf8数据的奇怪排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆