准备PHP应用程序以使用UTF-8

14

UTF-8现在已经成为Web应用程序的事实标准,但是PHP并不默认使用UTF-8编码(直到6.0版本)。大多数服务器默认设置为ISO-8859-1编码。

如何通过.htaccess重载默认设置,以确保UTF-8、本地化等一切正常?有没有针对Web服务器、Unix操作系统的任何选项?

是否有一个全面的列表列出这些设置?例如mbstring选项、iconv设置、本地化等等,我应该为每个多语言项目设置什么?有没有预定义的.htaccess示例?

(在我的具体情况下,我需要为英语、荷兰语和俄语设置。服务器在乌克兰。)


2
PHP 6.0 不会 -- 而且永远不会;至少,不会像我们期望的那样。 - Pascal MARTIN
@hakre,Pascal;对的,我的意思是Unicode感知,而不是UTF-8。 - Sfisioza
5个回答

15

.htaccess中一些有用的选项:

########################################
# Locale settings
########################################

# See: http://php.net/manual/en/timezones.php
php_value date.timezone "Europe/Amsterdam"

SetEnv   LC_ALL  nl_NL.UTF-8

########################################
# Set up UTF-8 encoding
########################################

AddDefaultCharset UTF-8
AddCharset UTF-8 .php

php_value default_charset "UTF-8"

php_value iconv.input_encoding "UTF-8"
php_value iconv.internal_encoding "UTF-8"
php_value iconv.output_encoding "UTF-8"

php_value mbstring.internal_encoding UTF-8
php_value mbstring.http_output UTF-8
php_value mbstring.encoding_translation On
php_value mbstring.func_overload 6

# See also php functions:
# mysql_set_charset
# mysql_client_encoding

# database settings
#CREATE DATABASE db_name
#   CHARACTER SET utf8
#   DEFAULT CHARACTER SET utf8
#   COLLATE utf8_general_ci
#   DEFAULT COLLATE utf8_general_ci
#   ;
#
#ALTER DATABASE db_name
#   CHARACTER SET utf8
#   DEFAULT CHARACTER SET utf8
#   COLLATE utf8_general_ci
#   DEFAULT COLLATE utf8_general_ci
#   ;

#ALTER TABLE tbl_name
#   DEFAULT CHARACTER SET utf8
#   COLLATE utf8_general_ci
#   ;

5
你说得没错,UTF-8是Web应用程序的一个不错的选择。
编码是处理数据的元信息。只要你知道(二进制)数据的编码,你就知道你在处理什么。如果你不知道编码,你就会迷失方向。我经常将其比喻为一个链条,如果编码链条中断了,数据也会被破坏。这对于显示数据和安全性都是正确的。
PHP本身是二进制的,它依赖于上下文/您来指定编码(例如,如何保存您的PHP源代码文件)。
所以我们来看一下一个简短(不完整)的清单:

操作系统

环境变量可能会告诉你正在使用的语言环境和编码。例如,文件系统的文件和目录名称都有自己的编码。我对这个问题并不十分熟悉,通常我们尝试使用英语来命名我们的文件,因此只使用US-ASCII字符范围是安全的,该字符集可用于ISO-8859-1UTF-8等拉丁扩展字符集。
当用户上传文件时,请记住过滤掉基本字母和标点符号,这样你几乎不会遇到任何问题(a-zA-Z0-9.-_),甚至为了视觉效果将它们全部转换为小写。
如果你觉得这会降低可用性,而文件系统并没有提供UTF-8范围内的Unicode字符,则可以回退到类似rawurlencode(百分号编码,三元组)这样的简单编码,并通过解析该名称到磁盘上来提供文件下载。
通常情况下,你只需要处理自己拥有的内容。开始询问一位普通的系统管理员或程序员有关字符编码的问题,大多数人会告诉你他们对此不太感兴趣。当然这是主观的,但如果你需要有人为你配置某些内容,这可能会有所不同。

HTML

这与PHP几乎无关,它涉及到你的脚本输出的领域。 通常的经验法则是:明确指定。如果你没有指定(HTML文件、CSS文件、Javascript文件),请不要指望它能正常工作。确保每个组件都知道自己的编码。否则,浏览器只能猜测。UTF-8是一个不错的选择,但我们的工作就是确保它的精确和明确定义。

PHP设置

作为一个经验法则,首先阅读随你的linux发行版一起提供的PHP包中的php.ini文件。它在注释中带有易读的文档和进一步的链接。以下是我想到的一些设置:

字符串

回答你的问题:设置和参数的需求始终取决于您使用的组件。对于像浏览器或Web服务器这样的通用组件,可以提供推荐设置以使其配置为 UTF-8 。但对于其他所有内容,都要视具体情况而定。最重要的是要寻找它,并确保您知道编码并可以进行配置/指定。通常会有文档记录。只要您不需要处理可移植代码,这就更简单了,因为您可以控制环境或仅需处理特定环境。编写有关编码的防御性代码,您应该就没问题了。

iconv和mb_string有什么区别? - CMCDragonkai

3
  1. All your files have to be saved in UTF-8 (without BOM) using your code editor.
  2. Webserver may be configured to send inappropriate headers, so it's recommended to override them in application level. For instance:

    header('Content-Type: text/html; charset=utf-8');
    
  3. Add HTML meta content-type:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
  4. Use htmlspecialchars() instead of htmlentities() because the former is enough in utf-8 and the latter is incompatible with utf-8 by default.

  5. Tend not to use PHP standard string functions because many of them are incompatible with utf-8. Try to find their counterparts in Multibyte String or other libraries. (Don't forget to set default charset for the library before using it because the library supports many encodings and utf-8 is just one of them.)
  6. For regular expressions use u modifier. For example:

    preg_match('/ž{3,5}/u', $string, $matches);
    

    Together this is the most reliable way to check if the given string is valid utf-8 string:

    if (@preg_match('//u', $string) === false) {
        // NOT valid!
    } else {
        // Valid!
    }
    
  7. If you use the database then always set appropriate connection encoding right after the connection is made. Example for MySQL:

    mysql_set_charset('utf8', $link);
    

    Also check if columns in the database are in utf-8. It's not always needed but recomended.


在正则表达式中,'/u'修饰符是否需要针对Unicode字符使用特定的注释符号? - Sfisioza
@Sfisioza 不太确定你的意思。如果你想要,你可以使用这种表示法来表示Unicode字符:\x{nnnn}。但通常情况下,如果你的文件已经保存为UTF-8格式,就不需要这样做了,因为你可以直接在正则表达式中写入Unicode字符,就像我在示例中所做的那样。在UTF-8中,有些字符占用多个字节。比如说我们有这个正则表达式:/ž{3}/u。这里的数字 3 表示字符数(而不是字节数),当 u 修饰符开启时。此外,还有一些针对正则表达式的特殊Unicode属性:http://www.php.net/manual/en/regexp.reference.unicode.php。 - Karolis
谢谢,这就是我所询问的内容。 - Sfisioza

1

基本上,我需要做三件事才能正确地使用捷克语:

1)在PHP中定义区域设置:

setlocale(LC_COLLATE, "cs_CZ");
setlocale(LC_CTYPE, "cs_CZ");

所以你可以使用类似这样的代码:

setlocale(LC_ALL, "en_US.utf8");
setlocale(LC_ALL, "nl_NL.utf8");

基于当前切换的语言。

2)为数据库定义字符集:

mysql_query("set names latin2 collate latin2_czech_cs");

3) 定义 PHP/HTML 代码的字符集:

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">

我没有使用任何 .htaccess 设置。您可以根据自己的情况进行修改,在语言环境中使用类似 en_US.utf8 的设置(基于当前正在使用的语言),在字符集方面请使用 utf-8 而不是 latin2/iso-8859-2,这样应该就能正常工作了。


0

请尝试以下方法之一:

 AddDefaultCharset UTF-8
 AddCharset UTF-8 .php

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