【发布时间】:2012-04-02 05:32:12
【问题描述】:
我们正在处理以前从未发生过的 Joyent Solaris 服务器中的一个奇怪错误(不会发生在 localhost 或其他两个具有相同 php 配置的 Solaris 服务器中)。其实我也不确定要不要看php还是solaris,是软件还是硬件的问题……
我只是想发布这个,以防有人能指出我们正确的方向。
所以,问题似乎出在var_export()处理奇怪字符时。
在 CLI 中执行此操作,我们在 localhost 机器和其中两台服务器中获得了预期的结果,但在第三台服务器中却没有。它们都配置为使用utf-8。
$ php -r "echo var_export('ñu', true);"
在较旧的服务器和本地主机中提供此功能(预期):
'ñu'
但是在服务器中我们遇到了问题(PHP 版本 => 5.3.6),它会在遇到“不常见”字符时添加 \0 空字符:è、á、ç , ...你的名字。
'' . "\0" . '' . "\0" . 'u'
知道应该在哪里看吗?提前致谢。
更多信息:
-
PHP version 5.3.6。 -
setlocale()没有解决任何问题。 -
default_charset在php.ini中是UTF-8。 -
mbstring.internal_encoding在php.ini中设置为UTF-8。 -
mbstring.func_overload = 0。 - 这发生在 CLI(示例)和 Web 应用程序(php-fpm + nginx)中。
-
iconv编码也是UTF-8 - 所有文件
utf-8编码。
system('locale') 返回:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_ALL=
目前完成的一些测试(CLI):
正常行为:
$ php -r "echo bin2hex('ñu');" => 'c3b175'
$ php -r "echo mb_strtoupper('ñu');" => 'ÑU'
$ php -r "echo serialize(\"\\xC3\\xB1\");" => 's:2:"ñ";'
$ php -r "echo bin2hex(addcslashes(b\"\\xC3\\xB1\", \"'\\\\\"));" => 'c3b1'
$ php -r "echo ucfirst('iñu');" => 'Iñu'
不正常:
$ php -r "echo strtoupper('ñu');" => 'U'
$ php -r "echo ucfirst('ñu');" => '?u'
$ php -r "echo ucfirst(b\"\\xC3\\xB1u\");" => '?u'
$ php -r "echo bin2hex(ucfirst('ñu'));" => '00b175'
$ php -r "echo bin2hex(var_export('ñ', 1));" => '2727202e20225c3022202e202727202e20225c3022202e202727'
$ php -r "echo bin2hex(var_export(b\"\\xC3\\xB1\", 1));" => '2727202e20225c3022202e202727202e20225c3022202e202727'
所以问题似乎出在var_export() 和"string functions that use the current locale but operate byte-by-byte" Docs(查看@hakre 的答案)。
【问题讨论】:
-
我首先检查每台服务器上运行的软件版本。特别是 php。一个版本中的函数采用 UTF-8,而不同版本中的相同函数采用 ISO-8859-1。
-
还可以尝试比较
locale(1)的输出和/或检查以LC开头的环境变量。 -
这只发生在 CLI 上吗?这可能是 Solaris 终端如何处理 Unicode 的一些特殊情况。或者从保证不包含
NUL字节的源代码文件运行时也会发生这种情况吗? -
检查两件事,一是在 CLI 上执行的 php.ini(可能与 web 服务器上的不同),将 default_charset 设置为“utf-8”。其次,检查 /etc/locale.gen 是否在那台服务器上有 en_US.UTF-8。
-
我确信这与 Solaris 和 PHP 使用的系统 C 库有关。我会说编译的包已经被宿主搞砸了,否则
strtoupper必须工作。获取正确的二进制文件。
标签: php utf-8 localization joyent