PHP/MySQL 编码问题

4
我有一个网站,内容为阿拉伯语,从不同的服务器迁移而来。在旧服务器上,所有内容都正确显示,假设一切都以 UTF-8 进行编码。
在当前服务器上,数据开始显示不正确,显示出“ نبذة عن ”等字符。
该应用程序基于 CakePHP 框架构建。
经过多次尝试,我将 MySql 连接数组中的“ encoding”参数更改为“ latin1”。对于不了解 CakePHP 的人来说,这将设置 MySql 的连接编码。即使在下面描述的步骤之后,将此值设置为 UTF8 也没有改变任何内容。
一些记录开始正确显示阿拉伯语,而其他记录仍然是乱码。
我已经进行了所有数据库和服务器检查,确认:
1.创建的数据库为 UTF-8。
2.表格为 UTF-8。
3.列没有明确设置编码,因此编码为 UTF-8。
4.PHP 中的默认字符集为 UTF-8
5.mysql.cnf 设置默认为 UTF-8
之后,我检索了我的数据并循环遍历它,使用 mb_detect_encoding 打印每个字符串(每行)的编码。显示正确的行返回 UTF8,而对于损坏的行则返回空值。
网站的数据已经被编辑过多次,可能使用不同的编码方式,这是我无法确定的。但我可以确认的是,这些数据可能通过的唯一两种编码方式是 UTF-8 和 latin1。
当 mb_detect_encoding 不返回任何内容且当前数据集未知时,是否有任何可能恢复数据?
更新:我发现在数据库在新服务器上运行时,my.cnf 已被更新。
以下指令已更改:
character-set-server=utf8
改为
default-character-set=utf8
不过,我不确定这是否有多大区别。
通过检查修改日期,我可以相对肯定地得出结论:我可以恢复的数据没有在新服务器上编辑,而无法检索的数据已被编辑。

如果你有phpmyadmin,你能在表格中看到你的数据吗?它的格式是否正确?我指的是阿拉伯字符。 - Mohammad Alabed
1
如果您的数据库中的数据损坏,那么问题不是来自Cackephp,而是来自数据库本身。请使用UTF8从旧服务器重新导出您的数据库。 - Mohammad Alabed
不,问题不在于CakePHP或者PHP。我只是强调了连接编码的使用。不幸的是,我无法再从旧服务器导出到新服务器了。我正在寻找解决方法: 1)获取损坏文本的实际编码 2)尝试将其改回正确的文本。 - Adon
@Adon,你还有旧服务器的导出文件吗?也许你可以查看那个文件中的文本。如果它没有正确导出,那么你可能有一个大问题,因为听起来你已经丢失了数据。 - drmonkeyninja
没有办法...据我所知,如果数据已经损坏,那么在数据库中修复它是不可能的。 - Mohammad Alabed
显示剩余4条评论
3个回答

0

尝试从数据库端解决问题,而不是从php或数据库连接方面解决

我建议您回到旧服务器并使用字符集UTF8再次导出您的数据库

然后在将其导入新服务器之后,请确保您可以在表格中看到阿拉伯字符(使用phpmyadmin) 如果您的表格看起来正常..

那么您可以继续检查下一个问题

  • 数据库连接

  • php文件编码

  • html中的标题编码

据我所知,如果问题来自数据库,则没有其他方法,只能从旧服务器重新导出数据

编辑:

如果您无法访问旧数据库,请查看this answer,它可能会对您有所帮助


正如我之前所述,我不再能够访问旧服务器。这个解决方案对我来说行不通。因为我有新的输入,所以我会在问题中发布更新。 - Adon
我会尽快检查并告诉你。谢谢。 - Adon
我读到过一些关于将数据库转换为二进制再转换回UTF8的方法...我不太确定...你可以在这里查看http://dev.mysql.com/doc/refman/5.0/en/charset-conversion.html。 - Mohammad Alabed

0

我曾经遇到过类似的问题,即从公共服务器迁移编码为utf8的数据库表到本地主机。解决方法是使用PHP设置本地主机服务器编码。

$db->set_charset("utf8") 

mysqli 连接之后。

现在它正常工作。


0
你期望看到的是 نبذة عن 吗?这是乱码。请参考duplicate以获取讨论和解决方案,包括如何通过一对ALTER TABLEs恢复数据。

这是正确的。我很好奇你是如何实现这个的。我已经尝试了这个解决方案,但它对我没有起作用。由于大小限制,我必须使用text数据类型而不是varchar,但我不认为这会导致问题,因为它们基本上存储相同的数据。 我正在使用mysql 5.5.42,但我也相信这不是问题,因为这种行为在所有最近的5.x版本中应该是相同的。 你有什么想法吗? - Adon
TEXTVARCHAR--它们的工作方式相同。版本5.x--自4.1以来,问题表现方式相同。BINARY(CONVERT('نبذة عن' USING latin1)) = نبذة عن。存储的数据应该是(十六进制):D986D8A8...;你所说的C383E284A2C3A2E282AC的HEX...更多讨论 - Rick James
是的,我得到了正确的十六进制字符串。问题在于将其转换回适当的字符串。它转换回相同的无法识别的文本。查询是 alter table dynamic_page_i18n modify COLUMN content varbinary(1000) NOT NULL DEFAULT ''; 然后是 alter table dynamic_page_i18n modify COLUMN content text CHARACTER SET utf8 NOT NULL DEFAULT '' ; 但是没有成功。我知道它们应该起作用,但它们没有。数据库是utf8,表是utf8,排序规则是utf8_general_ci。 - Adon
回顾一下。您在“content”中有Dxxx十六进制码,很好。您有“text ... CHARACTER SET utf8”,也很好。但是“SELECT”返回的是垃圾?这可能意味着连接不是“utf8”。您还可以在连接后立即执行“SET NAMES utf8;”。 - Rick James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接