我有一个很大的php对象,我想序列化并存储在MySql数据库中。表格编码为UTF-8
,保存序列化对象编码的列也为UTF-8
。
问题是该对象包含一个包含法语字符的文本字符串。
例如:
Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande
当我序列化对象然后再次反序列化它时,字符串被维护并且格式正确。
然而,当我将序列化对象存储到MySql数据库中然后再次检索它然后反序列化它时,字符串变成这样:
Merci d'avoir passé commande avec Lovre. Voici le récapitulatif de votre commande
将对象存储在数据库中时出现问题。
注意:
text
。答案 0 :(得分:11)
由serialize
创建的字符串是二进制字符串,它们没有特定的字符集编码,但只是字节的“数组”(其中 - 一个字节是8位,一个八位字节)。
如果您现在使用这样的字符串并告诉您的数据库它是LATIN-1编码的并且您的数据库将其存储到具有UTF-8编码的文本字段中,则数据库将透明地将编码从LATIN-1更改为UTF -8。 UTF-8是一种字符集编码,对于某些字符,每个字符使用多个字节,例如您在问题中提供的字符,如é
。
然后将字符é
存储为数据库é
,这是é
的UTF-8字节序列。
如果您现在从数据库中获取数据而未指定所需的编码,则数据库将以UTF-8的形式返回。
现在unserialize
有问题,因为二进制字符串已被修改为使其无效的方式。
相反,您需要告诉您的数据库在存储序列化字符串时不应修改编码,例如:通过选择正确的列类型和编码(二进制字段,BLOB - Binary Large ObjectMySQL Docs,同时参见Binary TypesPropel Docs) - 或者 - 从数据库中获取数据时,将charset-encoding恢复为原始格式。第一种方法(二进制字段)更好,因为它正是您正在寻找的。 p>
对于已经以错误格式存储到数据库中的数据,您需要更正数据。要做到这一点,首先需要找出应用了哪种重新编码,例如:从哪个charset到哪个charset。我认为它是LATIN-1但是没有保证。您需要查看当前应用程序数据和流程的编码以查找。
在您发现之后,将值从UTF-8编码回原始编码。
答案 1 :(得分:4)
确保使用utf-8 无处不在 - 听起来像你错过了什么。
在您的情况下,我认为您忘记为数据库连接设置正确的字符集(使用SET NAMES
语句或mysql_set_charset()) - 但如果没有看到您的代码,这很难说(我不知道推进)。
以下是来自chazomaticus的引用,她在 UTF-8 all the way through 中给出了完美答案,列出了您需要处理的所有要点:
存储
- 指定
utf8_unicode_ci
(或 等价)所有表格的整理 和数据库中的文本列。 这使得MySQL物理存储和 以UTF-8原生检索值。检索:
- 在PHP中,在任何DB包装器中 使用,你需要设置连接 字符串到utf8。这样,MySQL就可以了 没有从其原生UTF-8转换 当它将数据移交给PHP时。 * 请注意,如果您不使用数据库 包装,您可能不得不发布 一个查询告诉MySQL给你 结果为UTF-8:
SET NAMES 'utf8'
(一旦你连接)。交货:
- 你必须告诉PHP提供 对客户端的正确标头,所以 文本将被解释为UTF-8。在 PHP,你可以使用
default_charset
php.ini选项,或手动发出Content-Type
标题自己,哪个 只是更多的工作,但具有相同的 效果。提交:
- 您想要通过发送给您的所有数据 浏览器采用UTF-8格式。 不幸的是,唯一的方法 可靠地做到这一点就是添加
accept-charset
属于你的所有人<form>
代码:<form ... accept-charset="UTF-8">
。- 注 W3C HTML规范说明了这一点 客户“应该”默认发送 无论如何形成回服务器 charset服务器服务,但这是 显然只是一个推荐, 因此需要明确 每个
<form>
代码。- 虽然在那方面,你仍然会 想验证每个提交的字符串 在尝试之前作为有效的UTF-8 存放或在任何地方使用它。 PHP的
mb_check_encoding()
可以解决问题, 但你必须虔诚地使用它。处理:
- 不幸的是,这很难 部分。你需要确保这一点 每次处理UTF-8字符串时, 你安全地这样做了。最简单的方法 这是通过广泛使用 PHP的
mbstring
扩展名。- PHP的 字符串操作默认情况下不是 UTF-8安全。你有一些事情 可以安全地使用普通的PHP字符串 操作(如连接),但是 对于大多数事情你应该使用 等效
mbstring
函数。- 要 知道你在做什么(读:不要乱 它,你真的需要知道UTF-8 以及它如何在最低的工作 可能的水平。看看任何一个 来自utf8.com的链接有一些好处 学习所需资源的资源 要知道。
- 另外,我觉得这样 虽然应该在某个地方说 看起来很明显:每个PHP或HTML 你要服务的档案应该是 以有效的UTF-8编码。
请注意,您不需要使用utf-8 - 重要的部分是使用相同的charset无处不在,而不管可能是什么字符集。但如果你还需要改变一些东西,请使用utf-8。
答案 2 :(得分:1)
我总是使用base64_encode()
存储esrialized数据。
序列化数据有时会导致问题,但在使用它的base64值后,只剩下简单的字符。
答案 3 :(得分:1)
我强烈建议您使用json_encode而不是序列化。有一天,你会发现自己试图从另一个非PHP的地方使用这些数据并将其存储在JSON中,这使得它在任何地方都可读;几乎每种语言都支持解码JSON,并且是一个很好的标准。
关于在任何地方使用utf8的答案都有! :-D