我正在设置一个新的服务器,并希望在我的web应用程序中完全支持UTF-8。我过去曾在现有的服务器上尝试过这种方法,但似乎总是不得不回到ISO-8859-1。
我到底需要在哪里设置编码/字符集?我知道我需要配置Apache、MySQL和PHP来做到这一点-是否有一些标准的检查表,我可以遵循,或者排除哪里发生了不匹配?
这是一个新的Linux服务器,运行MySQL 5, PHP, 5和Apache 2。
我正在设置一个新的服务器,并希望在我的web应用程序中完全支持UTF-8。我过去曾在现有的服务器上尝试过这种方法,但似乎总是不得不回到ISO-8859-1。
我到底需要在哪里设置编码/字符集?我知道我需要配置Apache、MySQL和PHP来做到这一点-是否有一些标准的检查表,我可以遵循,或者排除哪里发生了不匹配?
这是一个新的Linux服务器,运行MySQL 5, PHP, 5和Apache 2。
当前回答
上面的答案很好。以下是我在常规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.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来提高性能。
我唯一想要补充的是,强调以UTF-8编码保存文件,我注意到浏览器接受这个属性,而不是设置UTF-8作为代码编码。任何像样的文本编辑器都会显示这一点。例如,notepad++有一个用于文件编码的菜单选项,它会显示当前的编码并允许您更改它。对于我所有的PHP文件,我使用UTF-8没有BOM。
前一段时间,有人让我为别人设计的PHP和MySQL应用程序添加UTF-8支持。我注意到所有的文件都是用ANSI编码的,所以我必须使用iconv来转换所有的文件,将数据库表更改为使用UTF-8字符集和utf8_general_ci排序,在连接后将' set NAMES utf8'添加到数据库抽象层(如果使用5.3.6或更早的版本)。否则,您必须在连接字符串中使用charset=utf8)并更改字符串函数以使用等价的PHP多字节字符串函数。
PHP中的Unicode支持仍然是一个巨大的混乱。虽然它能够将ISO 8859字符串(它在内部使用)转换为UTF-8,但它缺乏原生处理Unicode字符串的能力,这意味着所有的字符串处理函数都会破坏和破坏您的字符串。
因此,您必须使用单独的库来获得适当的UTF-8支持,或者自己重写所有字符串处理函数。
简单的部分是在HTTP头文件和数据库中指定字符集,但如果PHP代码没有输出有效的UTF-8,这些都无关紧要。这是最困难的部分,PHP在这方面几乎没有提供任何帮助。(我认为PHP 6应该能解决最糟糕的问题,但这还需要一段时间。)
上面的答案很好。以下是我在常规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()
就这些!
在我的例子中,我使用的是mb_split,它使用正则表达式。因此,我还必须手动确保正则表达式编码是UTF-8通过做mb_regex_encoding('UTF-8');
作为旁注,我还通过运行mb_internal_encoding()发现内部编码不是UTF-8,我通过运行mb_internal_encoding("UTF-8");来改变这一点。