【问题标题】:MySQL Wrong Order by varcharvarchar 的 MySQL 错误顺序
【发布时间】:2019-02-03 13:52:26
【问题描述】:

我使用 ACP 创建了一个页面并将我的数据保存在那里。一切运行都没有问题。但突然间我有一个神秘的问题。在公共区域我总是按字母顺序输出数据,但一个条目(“损坏的货物”)总是排在最后。

我的选择命令:

SELECT lyric_id, lyric_title, lyric_lang_00, lyric_text_00, lyric_lang_01,   
       lyric_text_01, lyric_lang_02, lyric_text_02, lyric_lang_03, lyric_text_03, 
       lyric_lang_04, lyric_text_04, lyric_lang_05, lyric_text_05 
FROM dnd_lyrics 
WHERE lyric_text_00!='' OR lyric_text_01!='' OR lyric_text_01!='' OR   
      lyric_text_02!='' OR lyric_text_03!='' OR lyric_text_04!='' OR 
      lyric_text_05!='' OR lyric_text_03!='' ORDER BY lyric_title ASC"

我要插入的命令:

$db->query("INSERT INTO dnd_lyrics (lyric_title,lyric_lang_00) 
  VALUES('".$db->str($_POST['lyric_title'])."','".$db->str($config['lang'])."')");

受影响的数据库: https://syntaxhigh.normanhuth.com/FlniL9

到目前为止,问题只发生在这一条目上。如果我通过 phpMyAdmin 手动输入,它可以工作。

【问题讨论】:

  • 名称前可能有空格或其他字符?还有哪些记录? var_dump 显示什么?您也可能对使用此代码的 SQL 注入持开放态度。
  • 查看您的数据,我可以在 ​Damaged Goods 看起来像一个可能的控制字符之前看到一个神秘字符,这就是问题所在。取决于编码显示为​
  • ​ 我看不到这个。 :O
  • 切换到ansi编码
  • 好的。谢谢。我从另一个带有曲目名称的表中获取自动收集内容,并且有一些相同的问题。现在我必须在那里搜索。谢谢。

标签: php mysql database mysqli utf-8


【解决方案1】:

测试了你的数据和你的查询,得到了这个结果:

. . .

|        8 | World War 3                        |
|       79 | W​+​J                              |
|       88 | ​Damaged Goods                     |
+----------+------------------------------------+

注意右栏的对齐方式。数据中有非打印空格。在我的屏幕上,它看起来像:

. . .

|        8 | World War 3                        |
|       79 | W ​+ ​J                              |
|       88 | ​ Damaged Goods                     |
+----------+------------------------------------+

“损坏的货物”标题在开头有一个额外的非打印空间,使其排在所有其他标题之后。

如果我在 vim 中打开你的数据,我会看到:

(88, '<200b>Damaged Goods', 'en',

Unicode 200b 是“零宽度空间”:https://www.fileformat.info/info/unicode/char/200B/index.htm

在将数据插入数据库之前,您应该对数据进行某种空白修剪操作。不幸的是,普通的 PHP trim() 函数不能完成这项工作。

请参阅Trim unicode whitespace in PHP 5.2 以获得解决方案。


你的评论:

您在 PHP 中使用 trim() 函数将不起作用。 PHP trim() 函数只能理解 ASCII 空白字符,而不是 unicode 类似空白字符。有关 trim 查找的字符列表,请参阅 http://php.net/trim

【讨论】:

  • 我直接在 MySQL 类中构建了 trim 函数 return $this->link->real_escape_string(trim($string));
  • Trim unicode whitespace in PHP 5.2 是我的解决方案。谢谢。
  • Hex('W​+​J') = 57 E2808B 2B E2808B 4A(添加一些间距)
【解决方案2】:

在数据库中确实有一个标志,不是立即可见的。可能在第一次使用 Javascript/Ajax 测试期间。

Bill Karwin 的建议很有帮助。 我在我的 MySQL 类中添加了“Trim unicode whitespace in PHP 5.2”函数。 并且只需循环遍历表并使用此函数重写内容,从而使数据库干净。

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    相关资源
    最近更新 更多