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

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

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


当前回答

我刚刚经历了同样的问题,并在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());
}

查看源代码

其他回答

上面的答案很好。以下是我在常规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 5.3.5及以下版本。不要在PHP 5.3.6版本(2011年3月发布)或更高版本中使用它。 比较Palec的回答PDO + MySQL和破碎的UTF-8编码。


我发现了一个问题,有人使用PDO,答案是使用这个PDO连接字符串:

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

我刚刚经历了同样的问题,并在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());
}

查看源代码

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

解决办法就是使用

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

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

如果你想让MySQL服务器来决定字符集,而不是PHP作为客户端(旧行为;最好,在我看来),尝试添加skip-character-set-client-handshake到my.cnf,在[mysqld]下,并重新启动mysql。

如果您使用的不是UTF-8,这可能会带来麻烦。