【问题标题】:Correct "Incorrect string value" in MySQL without amending the databases encoding在不修改数据库编码的情况下更正 MySQL 中的“不正确的字符串值”
【发布时间】:2020-10-06 10:56:12
【问题描述】:

PHP: 7.2.5 Laravel: 7.25

我们有一个错误,即极少数用户试图插入带有“????”的副本包括字符。我假设这是因为从 PDF 复制和粘贴,我之前已经看到它们带有换行符。这会产生以下错误:

SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF4\x8F\xB0\x80</...' for column 'body' at row 1 (SQL: update `post` set `body` = <p>????</p>, `body_raw` = ????, `post`.`updated_at` = 2020-10-06 10:34:22 where `id` = 1)

字符'????':

  • 十进制字符代码:56319、56320
  • 十六进制字符代码:0xdbff, 0xdc00
  • 带有命名字符引用的 HTML:&amp;#xdbff; &amp;#xdc00;

查看 Google,建议您可以从 utf8 to utf8mb4 更新 DB 编码。这可能是最佳解决方案,但我们有一个大型数据库,我对修改编码感到不安(尽管这可能非常安全)。我担心可能的数据丢失/损坏。

由于此问题仅出现在我们的错误系统中的这 1 个字符上,并且 100% 不需要,因此我倾向于在将其保存到数据库之前将其删除,以创建最少的更改。

我倾向于做以下事情:

str_replace("????","", $post);

但如果我粘贴字符 '????'在我的任何代码编辑器中它都会消失(我假设是 utf8 编码)。实现这一目标的最佳方法是什么?

【问题讨论】:

  • 您的数据库排序规则是什么?我认为不是utf8mb4_unicode_ci
  • \xF4\x8F\xB0\x800xdbff, 0xdc00 有什么区别?
  • “但是如果我粘贴字符 '????'进入我的任何代码编辑器,它就会消失” - 作为替代方案,您可以使用 chr 从(十进制)整数字节值创建正确的字节序列。
  • 制作urlencode($post-&gt;body)的调试输出,该位置的百分比编码将有助于检查您实际处理的字节值。
  • @sta 这正是我想要完成的,但如果你将代码复制到 PhpStorm 或 Sublime 文本中,特殊字符就会消失。我找到了一个解决方案,写在下面。不过感谢您的帮助。

标签: php mysql laravel laravel-7


【解决方案1】:

在@04FS 的大力帮助下(谢谢)。我找到了解决方案。如前所述,我认为数据库 utf8 到 utf8mb4 修复可能是这里的最佳途径。但是为了不修改数据库,这里是我找到的解决方案。

这里主要的混淆问题是字符“?”。由于我无法将其输入到我的文本编辑器中,因此很难使用。所以我依靠 3rd 方网站对其进行编码。一个建议是使用 char() 来编写和匹配字符。但是在 2 个不同的网站上,字符代码同时出现 char(111) 和 char(244)。使用 char(244) 我可以使用 str_replace,但它只创建了部分替换并破坏了 SQL 查询。

@04FS 提到尝试 urlencode(),它给了我 '%F4%8F%B0%80' 的那个字符。这与数据库错误匹配。所以以下解决方案可以正常工作:

  private function removeSpecialCharacters($str) {
      $str = str_replace(urldecode('%F4%8F%B0%80'), '', $str);
      return $str;
  }

【讨论】:

    猜你喜欢
    • 2013-03-22
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多