【问题标题】:Issues with stored JSON encoded POSTs in MySQLMySQL 中存储的 JSON 编码 POST 的问题
【发布时间】:2011-04-30 09:34:45
【问题描述】:

我有一种情况,经过几年的使用,我们突然有了一些 JSON 编码的值,由于反斜杠,这些值使我们的 Perl 脚本适合。

问题在于 í 和 é 等重音字符。一个例子是 Matí 编码为 Mat\ud873。

目前尚不清楚环境中可能发生了什么变化。涉及 PHP、Perl 和 MySQL。表排序规则是 latin1_swedish_ci,这可能已被同事搞砸了。

这会给任何人敲响警钟吗?

【问题讨论】:

  • 为什么只存储部分代理?
  • 嗨,Ignacio,不确定我是否关注?系统从表单中获取整个帖子,并使用 Pear 模块对整个 $_POST 进行编码,就像 $json->encode($_POST); 一样,并存储到 mySQL 以供 Perl 稍后处理。
  • 你能告诉我们它在所有不同阶段是如何输入、编码和存储的吗?
  • U+D873 是代理对的一半。 UTF-16 中使用代理对来描述 BMP 之外的字符。
  • 谢谢!这可以理解 Perl 中的错误:在代理对中缺少低代理字符,在字符偏移 161 处(在 "nd \\u9000","name_la..." 之前)

标签: php mysql perl json collation


【解决方案1】:

这里的问题是 JavaScript 端的国际化,而不是数据库表的排序规则。如果您之前没有遇到此类问题,则可能之前没有用户输入国际字符,或者您的 HTML 页面的字符集是 ISO-8859-1/cp1252(这将限制客户端上的 POST 数据。)新用户或更改的 HTML 标头可能会导致此问题表现出来,但问题确实出在 Perl 脚本方面。

JSON defines strings as double-quoted sets of characters with Unicode escape sequences 需要超过 7 位编码时。前 127 个 ISO-8859-1 字符可以按原样表示,但任何扩展 ASCII/多字节字符最终都将作为 \uXXXX 值。例如,字符 é (e-acute),在 ISO-8859-1 中是 #233 将显示为 \u00E9(因为 é 在 Unicode 中是 U+00E9),字符串“resume”将存储为“r \u00E9sum\u00E9"。

不知道您的 Perl 脚本试图做什么,我只能说在尝试取消引用转义序列时可能会遇到困难。 Perl 有自己的一组转义序列,而 \u 中间字符串实际上意味着“使下一个字符大写”,因此您可能 看到很多来自 Perl 的“00E9”内容脚本而不是重音字符,否则您可能会遇到解析错误,具体取决于您的脚本。

由于您是在 PHP 中从 POST 数据创建/存储 JSON,因此您有一些选择:

  1. 将特殊字符转换为 HTML 实体 (htmlentities())
  2. 通过utf8_decode() 强制所有特殊字符从 UTF-8 序列(如果这是您的 POST 数据进来的内容)减少到 ISO-8859-1(您可能会丢失数据使用这种方法)
  3. 通过将此 REGEX 匹配项替换为 /\\u[a-zA-Z0-9]{4,4}/ 来清理生成的 JSON 为“”(无)(您可能会丢失数据用这种方法)
  4. 在将结果 JSON 输入到 Perl 脚本之前,通过将所有“\”字符更改为“\\”对结果 JSON 进行双重转义(小心 SQL 注入!

【讨论】:

  • 我很确定这是由于环境变化造成的。存储了来自世界各地的 178000 多个个人提交,我发现了这个问题,因为它导致 Perl cron 作业抛出了前三年没有发生的错误。我希望避免对数据应用正则表达式,但这可能是我最好的选择。
  • 非常感谢您在回复中的时间和麻烦。它确实帮助我更深入地思考了这一点。
  • 在对数据进行 JSON 化之前在 PHP 端强制进行 8 位编码可以解决问题,同时减少数据丢失。当然,Perl 可以处理 Unicode,所以教它在内部转换 \uXXXX 引用是最好的选择,并且可以保留所有数据。
  • Jay - Ignacio 上面的评论让我终于明白 Perl 在抱怨什么。我虽然这是逃避,但这是代理对的问题。我应该删除这个问题并提出新问题吗?
  • 耶! htmlentities() 拯救了这一天!当我存储时我编码,当我膨胀时我解码,生活是美好的!谢谢!
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
相关资源
最近更新 更多