迁移一个处理UTF-8的php应用程序

16 浏览
0 Comments

迁移一个处理UTF-8的php应用程序

我正在开发一个使用PHP的多语言应用程序。

一切都很顺利,直到最近被要求支持中文字符。为了支持UTF-8字符,我采取了以下措施:

  • 所有数据库表现在都是UTF-8编码
  • HTML模板中包含标签
  • 控制器发送一个指定编码(utf-8)的头部,用于HTTP响应

一切都好,直到我开始进行一些字符串操作(如substr等)。

对于中文来说,这样做行不通,因为中文是由多个字节表示的,所以如果你使用普通的子字符串(substr),它可能会在一个字节分配的字符中间截断一个“字母”,导致结果在屏幕上出错。

通过在引导文件中添加以下代码mb_internal_encoding("UTF-8");并将所有的strlensubstrstrstr替换为它们的mb_相应函数,我解决了所有问题。

还有哪些事情我需要做来完全支持PHP中的UTF-8编码?

0
0 Comments

问题:将一个php应用程序迁移到处理UTF-8的问题。

原因:

1. 在PCRE正则表达式中,需要添加utf8标志,以便将模式解释为实际的字符而不是字节。

2. 应使用Unicode字符类代替标准Perl字符类,以确保正则表达式对非拉丁字母正确。

解决方法:

1. 在PCRE正则表达式中添加utf8标志。

2. 使用Unicode字符类替代标准Perl字符类。

3. 替换一些函数为多字节版本。

4. 在MySQL配置文件中设置字符集和排序规则。

5. 在PHP ini文件中设置mb_internal_encoding,并设置其他推荐参数。

6. 在表单中设置accept-charset为UTF-8,以告诉浏览器以UTF-8提交表单。

7. 在表单中添加隐藏字段,以防止一些浏览器以其他编码方式提交表单。

8. 在Apache配置文件中设置"AddDefaultCharset utf-8"。

9. 在HTTP头部设置meta content-type。

文章如下:

将一个php应用程序迁移到处理UTF-8的问题

在将php应用程序迁移到处理UTF-8的过程中,有一些需要注意的事项。除了简单地替换函数外,还需要对正则表达式和数据库进行特殊处理。

正则表达式是处理字符串的重要工具之一。在处理可能包含非ASCII字符的字符串时,需要添加utf8标志,以确保模式被解释为实际字符而不是字节。例如,可以使用以下代码添加utf8标志:

$subject = "Helló";
$pattern = '/(l|ó){2,3}/u'; //The u flag indicates the pattern is UTF8
preg_match($pattern, substr($subject,3), $matches, PREG_OFFSET_CAPTURE);

此外,应使用Unicode字符类替代标准Perl字符类,以确保正则表达式对非拉丁字母正确。例如,可以使用`\p{L}`替代`\w`表示任何“字母”字符,使用`\p{Z}`替代`\s`表示任何“空格”字符,使用`\p{N}`替代`\d`表示任何“数字”字符。

在函数方面,需要替换一些函数为多字节版本。以下是一些需要替换的函数及其替代函数:

$unsafeFunctions = array(
    'mail'      => 'mb_send_mail',
    'split'     => null, //'mb_split', deprecated function - just don't use it
    'stripos'   => 'mb_stripos',
    'stristr'   => 'mb_stristr',
    'strlen'    => 'mb_strlen',
    'strpos'    => 'mb_strpos',
    'strrpos'   => 'mb_strrpos',
    'strrchr'   => 'mb_strrchr',
    'strripos'  => 'mb_strripos',
    'strstr'    => 'mb_strstr',
    'strtolower'    => 'mb_strtolower',
    'strtoupper'    => 'mb_strtoupper',
    'substr_count'  => 'mb_substr_count',
    'substr'        => 'mb_substr',
    'str_ireplace'  => null,
    'str_split'     => 'mb_str_split', //TODO - check this works
    'strcasecmp'    => 'mb_strcasecmp', //TODO - check this works
    'strcspn'       => null, //TODO - implement alternative
    'strrev'        => 'mb_strrev', //TODO - check this works
    'strspn'        => null, //TODO - implement alternative
    'substr_replace' => 'mb_substr_replace',
    'lcfirst'       => null,
    'ucfirst'       => 'mb_ucfirst',
    'ucwords'       => 'mb_ucwords',
    'wordwrap'      => null,
);

在处理MySQL时,需要注意设置正确的字符集和排序规则。设置字符集为`utf8mb4`,排序规则为`utf8mb4_unicode_ci`。这样可以支持包括4字节编码字符在内的所有UTF-8字符。具体设置如下:

[mysql]

default-character-set=utf8mb4

[client]

default-character-set=utf8mb4

[mysqld]

init-connect='SET NAMES utf8mb4'

character-set-server=utf8mb4

collation-server=utf8mb4_unicode_ci

此外,在PHP ini文件中设置`mb_internal_encoding`为`UTF-8`,并设置其他推荐参数,如下所示:

mbstring.language = Neutral ; Set default language to Neutral(UTF-8) (default)

mbstring.internal_encoding = UTF-8 ; Set default internal encoding to UTF-8

mbstring.encoding_translation = On ; HTTP input encoding translation is enabled

mbstring.http_input = auto ; Set HTTP input character set dectection to auto

mbstring.http_output = UTF-8 ; Set HTTP output encoding to UTF-8

mbstring.detect_order = auto ; Set default character encoding detection order to auto

mbstring.substitute_character = none ; Do not print invalid characters

default_charset = UTF-8 ; Default character set for auto content type header

为了确保浏览器正确选择UTF-8编码的表单提交,需要在表单中设置`accept-charset`为UTF-8,并在表单中添加隐藏字段,以防止某些浏览器以其他编码方式提交表单。

除了上述内容,还有一些其他细节需要注意,如在Apache配置文件中设置`AddDefaultCharset utf-8`,在HTTP头部设置meta content-type等。

通过按照以上方法处理不同的问题,可以成功将php应用程序迁移到处理UTF-8编码,从而避免处理不同字符集所带来的麻烦。

0