除了替换这些功能之外,还有更多内容。
常用表达
您应该将 utf8 标志添加到所有可以包含非 Ascii 字符的字符串的 PCRE 正则表达式中,以便将模式解释为实际字符而不是字节。
$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 用于任何“数字”字符,例如阿拉伯数字
有许多不同的 Unicode 字符类别,其中一些对于习惯于用拉丁字母阅读和写作的人来说是非常不寻常的。例如,一些字符与前一个字符组合形成一个新的字形。可以在此处阅读有关它们的更多说明。
虽然mbstring扩展中有正则表达式函数,但不推荐使用。标准 PCRE 函数与 UTF8 标志一起工作正常。
功能替换
虽然您的列表是一个开始,但到目前为止我发现需要用多字节版本替换的函数列表更长。这是带有替换函数的函数列表,其中一些函数没有在 PHP 中定义,但可以从Github 上的 mb_extra 获得。
$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
尽管您会认为将字符类型设置为utf8
会在 MySQL 中为您提供 UTF-8 支持,但事实并非如此。
它只为您提供对最多 3 个字节编码的 UTF-8 的支持,也就是Basic Multi-lingual Plane。然而,人们正在积极使用需要 4 个字节进行编码的字符,包括大多数表情符号字符,也称为补充多语言平面
为了支持这些,您通常应该使用:
- utf8mb4 - 用于您的字符编码。
- utf8mb4_unicode_ci - 用于您的字符排序。
对于特定场景,有可能适合您的替代排序规则集,但通常坚持使用最正确的排序规则集。
您应该在 MySQL 配置文件中设置字符集和排序规则的位置列表是:
[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
可能并非在所有情况下SET NAMES
都需要 - 但它只在很小的速度损失时更安全。
PHP INI 文件
尽管您说您已在引导脚本中设置了 mb_internal_encoding,但最好在 PHP ini 文件中执行此操作,并设置所有推荐的参数:
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
帮助浏览器为表单选择 UTF8
杂项
应该是这样的。尽管值得一读“ What Every Programmer Absolutely, Positively Needs To Know About Encodings and Character Sets To Work With Text ”页面,但我认为最好在任何地方都使用 UTF-8,这样就不必花费任何精力来处理不同的字符集。