PHP / MySQL编码问题。 而不是某些字符

时间:2012-10-20 02:53:33

标签: php mysql utf-8 character-encoding collation

使用php将某些字符输入我的mysql数据库时遇到了一些问题。我正在做的是将用户输入的文本提交到数据库。我无法弄清楚我需要改变什么以允许将任何类型的字符放入数据库并通过php打印出来,如其所想。

我的MySQL排序规则是:latin1_swedish_ci

在我从表单发送文本到数据库之前,我在数据上使用了mysql_real_escape_string()。

以下示例

本文:

�People are just as happy as they make up their minds to be.�
� Abraham Lincoln 

假设看起来像这样:

“People are just as happy as they make up their minds to be.”
― Abraham Lincoln

7 个答案:

答案 0 :(得分:7)

正如其他人所说,如果你想支持“特殊”字符,你需要从头到尾转换为UTF8。这意味着您的网页,PHP,mysql连接和mysql表。网页相当简单,只需使用UTF8的元标记即可。理想情况下,你的标题也会说UTF8。

<meta http-equiv="content-type" content="text/html; charset=utf-8" />

将PHP设置为使用UTF8。无论如何,事情可能会奏效,但这是一个很好的措施:

mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_http_input('UTF-8');

对于mysql,您希望将表转换为UTF8,无需导出/导入。

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8

您可以而且应该将mysql配置为默认utf8。但您也可以运行查询:

 SET NAMES UTF8

作为建立连接后的第一个查询,并将数据库连接“转换”为UTF8。

这应解决所有角色显示问题。

答案 1 :(得分:3)

问题的最可能原因是数据库连接设置为latin1,但您正在为其提供以UTF-8编码的文本。解决此问题的最简单方法是将输入转换为客户期望的内容:

$quote = iconv("UTF-8", "WINDOWS-1252//TRANSLIT", $quote);

(MySQL称之为latin1的是世界其他地方的windows-1252。)请注意,许多字符,例如您在那里使用的引用短划线U + 2015,无法在此编码中表示,并且被转换成别的东西。理想情况下,您应该将列编码更改为utf8

替代解决方案:将数据库连接设置为utf8。列的编码方式无关紧要:MySQL在内部将文本从连接编码转换为存储编码,如果需要,可以将列保留为latin1。 (如果您这样做,报价短划线U + 2015将变为问号?,因为它不在latin1

如何设置连接编码取决于您使用的库:如果您使用已弃用的MySQL库,则为mysql_set_charset,如果MySQLi为mysqli_set_charset,则PDO将encoding=utf8添加到DSN。

如果这样做,您将使用Content-Type标头将页面编码设置为UTF-8。 否则你会遇到与浏览器相同的问题:当它需要别的东西时,用UTF-8编码的文本:

header("Content-Type: text/html; charset=utf-8");

答案 2 :(得分:1)

如果从头开始,提供的解决方案是有用的。将所有可能的连接放到UTF-8上确实是最安全的。由于各种原因,UTF-8是网上最常用的字符集。

一些建议和警告:

  • 复制要使用唯一前缀(tmp_)清理的表
  • 虽然您的数据库连接被强制为utf8,但请检查“常规设置”排序规则,如果尚未完成,请更改为 utf8_bin
  • 您需要在本地服务器上运行
  • 有趣的char错误主要是由于将LATIN1与UTF-8配置混合在一起。此解决方案专为此而设计。它可以与LATIN1使用的其他使用过的字符集一起工作,但我没有检查过这个
  • 检查这些tmp_tables,然后再复制回原来的

构建魔法所需的2数组:

$chars = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES, "UTF-8");
$LATIN1 = $UTF8 = array();
while (list($key,$val) = each ($chars)) {
    $UTF8[] = $key;
    $LATIN1[] = $val;
}

现在建立你需要的例程:( tables-&gt;)rows-&gt;字段和每个字段调用

$row[$field] = mysql_real_escape_string(str_replace($LATIN1 , $UTF8 , $row[$field]));
$q[] = "$field = '{$row[$field]}'";

最后建立并发送查询:

mysql_query("UPDATE $table SET " . implode(" , " , $q) . " WHERE id = '{$row['id']}' LIMIT 1");

答案 3 :(得分:0)

将MySQL排序规则更改为utf8_unicode_ci或utf8_general_ci,包括表和数据库。

答案 4 :(得分:0)

您需要在utf-8中设置数据库。有很多方法可以做到这一点。通过改变配置文件,通过phpmyadmin或者在插入和更新mysql之前调用php函数(抱歉内存空白)。

不幸的是,我认为您必须重新输入之前输入的任何数据。

您还需要了解一件事,从个人经验来看,确保所有关系表都具有相同的排序规则,否则您将无法加入它们。

作为参考:http://dev.mysql.com/doc/refman/5.6/en/charset-syntax.html

另外,我可以成为一个apache设置。我们在“免费托管”服务器以及我兄弟的服务器上遇到了同样的问题。一旦切换到另一台服务器,所有的charater变得整洁。 Verfiy你apache设置,对不起,但我不能更多关于apache的配置。

答案 5 :(得分:0)

摆脱你需要遵循这两点的一切,解决有关特殊语言字符的每一个问题。

1-您需要将表的排序规则定义为utf8_general_ci。

2-在头标记之后的HTML中定义<meta http-equiv="content-type" content="text/html; charset=utf-8">

2-您需要在与数据库建立连接的文件中定义mysql_set_charset('utf8',$link_identifier);,并在选择数据库之后立即使用'mysql_set_charset',这将允许您添加和检索数据正确地说它是什么语言。

答案 6 :(得分:0)

如果您的文本已使用错误的编码进行编码和解码,因此实际上 mojibake 已“固化”为 unicode 字符,那么到目前为止提到的解决方案将不起作用。我最终成功使用 ftfy Python 包自动检测/修复 mojibake:

>>> import ftfy
>>> print(ftfy.fix_encoding("(ง'⌣')ง"))
(ง'⌣')ง

希望这对处于类似情况的人有所帮助。