我正在设置一个新的服务器,并希望在我的web应用程序中完全支持UTF-8。我过去曾在现有的服务器上尝试过这种方法,但似乎总是不得不回到ISO-8859-1。

我到底需要在哪里设置编码/字符集?我知道我需要配置Apache、MySQL和PHP来做到这一点-是否有一些标准的检查表,我可以遵循,或者排除哪里发生了不匹配?

这是一个新的Linux服务器,运行MySQL 5, PHP, 5和Apache 2。


当前回答

除了在php.ini中设置default_charset外,你还可以在输出之前使用header()在你的代码中发送正确的字符集:

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

在PHP中使用Unicode是很容易的,只要您认识到大多数字符串函数都不能使用Unicode,而且有些函数可能会完全破坏字符串。PHP认为“字符”长度为1字节。有时这是可以的(例如,explosion()只查找字节序列并将其用作分隔符——因此查找的实际字符并不重要)。但在其他时候,当函数实际设计为处理字符时,PHP并不知道您的文本中有Unicode中可以找到的多字节字符。

phputf8是一个很好的库。这将重写所有“坏”函数,因此您可以安全地处理UTF8字符串。也有像mb_string扩展这样的扩展试图为您做这件事,但我更喜欢使用库,因为它更可移植(但我写的是大众市场产品,所以这对我来说很重要)。但是phputf8可以在幕后使用mb_string来提高性能。

其他回答

我刚刚经历了同样的问题,并在PHP手册中找到了一个很好的解决方案。

我把所有文件的编码改为UTF8,然后是连接上的默认编码。这解决了所有的问题。

if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
   printf("Current character set: %s\n", $mysqli->character_set_name());
}

查看源代码

对于chazomaticus的精彩回答,我想补充一点:

也不要忘记META标签(像这样,或者它的HTML4或XHTML版本):

<meta charset="utf-8">

这看起来微不足道,但IE7以前就给过我这样的问题。

我做的每件事都是对的;数据库、数据库连接和内容类型HTTP头都被设置为UTF-8,在所有其他浏览器中都能正常工作,但ie仍然坚持使用“西欧”编码。

结果发现这个页面缺少META标签。加上这个,问题就解决了。

编辑:

W3C实际上有相当大的一部分专门讨论I18N。他们有很多关于这个问题的文章——描述HTTP, (X)HTML和CSS方面的事情:

常见问题:更改(X)HTML页面编码为UTF-8 在HTML中声明字符编码 教程:XHTML, HTML和CSS中的字符集和编码 设置HTTP字符集参数

他们建议同时使用HTTP报头和HTML元标记(或者在XHTML作为XML的情况下使用XML声明)。

我最近发现,使用strtolower()可能会导致数据在特殊字符之后被截断的问题。

解决办法就是使用

mb_strtolower($string, 'UTF-8');

mb_使用MultiByte。它支持更多的字符,但总体来说有点慢。

上面的答案很好。以下是我在常规Debian、PHP和MySQL设置中所做的:

// Storage
// Debian. Apparently already UTF-8

// Retrieval
// The MySQL database was stored in UTF-8,
// but apparently PHP was requesting ISO 8859-1. This worked:
// ***notice "utf8", without dash, this is a MySQL encoding***
mysql_set_charset('utf8');

// Delivery
// File *php.ini* did not have a default charset,
// (it was commented out, shared host) and
// no HTTP encoding was specified in the Apache headers.
// This made Apache send out a UTF-8 header
// (and perhaps made PHP actually send out UTF-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// Submission
// This worked in all major browsers once Apache
// was sending out the UTF-8 header. I didn’t add
// the accept-charset attribute.

// Processing
// Changed a few commands in PHP, like substr(),
// to mb_substr()

就这些!

在PHP中,您需要使用多字节函数,或者打开mbstring.func_overload。这样,如果你的字符超过一个字节,像strlen这样的东西就可以工作。

你还需要确定你的回答的字符集。您可以像上面一样使用AddDefaultCharset,也可以编写返回标头的PHP代码。(或者你可以在你的HTML文档中添加一个META标签。)