【问题标题】:PHP vs Python Handling of Unicode Values stored in DBPHP vs Python 处理存储在数据库中的 Unicode 值
【发布时间】:2015-10-29 02:20:25
【问题描述】:

我有一个 PHP 支持的网站,可以处理来自 JSON 的数据输入。 JSON 输入存储在数据库中,然后显示给用户。普通的东西……

现在我正在尝试使用 Python 脚本来处理添加类似数据的问题,但遇到了 Unicode 问题。即,Python 使用MySQLdb 输入数据库的特殊字符在显示页面时(通过 PHP/HTML)不会正确显示。

这是一个例子:

  • JSON 来源:© 2015


  • 来自 PHP 插入的数据库中的数据:© 2015

  • PHP DB 在网络上的样子插入:© 2015


  • 来自 Python 的 DB 中的数据插入 © 2015

  • 从 Python 数据库插入到 Web 上的样子:� 2015

MySQLdb 的通用代码(comment<type 'unicode'>,我遇到了麻烦):

db = MySQLdb.connect("localhost", "root", "pass", "database",
    use_unicode=True, charset='utf8' )

dbc = db.cursor()

dbc.execute("INSERT INTO `marks` (`id`, `title`, `comment`) VALUES (NULL, %s, %s)",
    [ title, comment ])

db.commit()
db.close()

在输出端,我使用 PHP DOMDocument 将文本加载并打印为 HTML:

@$descriptionText->loadHTML( '<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$mark['Mark']['comment'] );
echo $descriptionText->saveHTML();

因此,PHP 正在对数据库中的数据进行编码,以便在转储出来时看起来很奇怪,但在编码为 HTML 时可以正确呈现。有什么办法可以在 Python 中复制这种行为?

【问题讨论】:

  • 我厌倦了将 db 设置为不使用 unicode 的测试:db = MySQLdb.connect("localhost", "root", "pass", "database") 但无论哪种方式似乎都无关紧要(仍然得到� 2015 输出)。
  • 你正在深入。 Mojibake (©); 是另一个。如果您需要进一步的建议,请启动另一个线程,并包含 SELECT col, HEX(col) FROM .. WHERE .. 以作为这两种情况的示例。
  • 谢谢@RickJames;那条评论很旧,实际上在@metatoaster 下面的回答之后我就开始工作了

标签: php python mysql unicode


【解决方案1】:

由于您没有从您的 PHP 支持的网站生成任何代码,我们无法确定它是否正确处理 unicode,或者根本无法确定。如果来自 PHP 插入的 DB 中的数据确实(如问题所述)显示为 © 2015(特别是 python 字符串 u'\xc2\xa9 2015',请注意 u 将其表示为 unicode 字符串),那么您的 PHP 应用程序实际上做了什么insert 使用utf-8 编解码器对输入的unicode 字符串进行解码,然后在数据库插入中,所有内容都被编码为ISO8859-1(或latin1)。加载时,查询返回一个latin1 字符串,PHP 应用程序使用utf8 编解码器对其进行解码以取回原始unicode。

对于 Python 代码,由于所有操作都在 utf8 中完成,没有 latin1 步骤,当 PHP 脚本尝试加载该数据时,它将尝试解码失败,因为字节 \xa9 是一个错误并且PHP 默认使用\ufffd unicode 代码点替换错误。

要使您的 Python 插入与您的 PHP 网站兼容并作为测试以查看此推断是否正确,请尝试

dbc.execute("INSERT INTO `marks` (`id`, `title`, `comment`)"
    "VALUES (NULL, %s, %s)", [
        title.encode('utf8').decode('latin1'),
        comment.encode('utf8').decode('latin1'),
])

这基本上将所有 unicode 转换为您的 PHP 应用程序所期望的原始 latin1 代码点,因为正如我所提到的,它可能假定所有表都是 utf8 编码字符串,由 latin1 字符集表示。

【讨论】:

  • 谢谢! comment.encode('utf8').decode('latin1') 就是所需要的。我不确定如何更好地报告 PHP 代码,因为我认为数据库插入是由框架处理的,但无论如何你都能弄清楚。所以不会让我奖励赏金,但我明天会。
  • 经过更多测试后,它可以使用一些 unicode 字符(如 ©),但不能使用其他字符。例如。对于 u'Wies\u0142aw'encode('utf8').decode('latin1') 的 Python 的 unicode 输入,将其转换为 u'Wies\xc5\x82aw' 并且在查看网页上的网页时我得到了Wies�?aw。解决方案是 disable 使用 unicode 和 DB;基本上是db = MySQLdb.connect("localhost", "root", "pass", "database") 而不是db = MySQLdb.connect("localhost", "root", "pass", "database", use_unicode=True, charset='utf8' )
  • 您可能还想通过SHOW CREATE TABLE marks 来调查表是否使用utf8 编码,并查看DEFAULT CHARSET 是否为utf8
  • 谢谢,是的,DEFAULT CHARSET=utf8。我猜这意味着真的是我的 PHP 表现不佳?
  • 正确,很可能按照我描述的方式行事(假设表中的所有内容都是实际字节,并在发送到客户端之前将其编码为 utf8)。正确的行为是程序(PHP或Python)写入数据库的原始数据应该是正确的utf8编码,但正如你所描述的,PHP代码没有这样做,必须修改Python以遵循使最终用户看起来正确的错误方法。
猜你喜欢
  • 2013-12-10
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多