我们正在处理之前从未发生过的Joyent Solaris服务器中的一个奇怪的错误(不会发生在localhost或其他两个具有相同php配置的Solaris服务器上)。实际上,我不确定我们是否必须查看php或solaris,以及它是否是软件或硬件问题......
我只想发布这个,以防有人指出我们正确的方向。
因此,在处理奇怪的字符时,问题似乎出现在var_export()
中。
在CLI中执行此操作,我们在localhost机器和两个服务器中获得预期结果,但不在第三个服务器中获得。所有这些都配置为使用utf-8
。
$ php -r "echo var_export('ñu', true);"
在较旧的服务器和localhost (预期):
中提供此功能'ñu'
但是在服务器中我们遇到了( PHP Version => 5.3.6 )的问题,每当遇到“不常见”字符时它会添加\0
个空字符:è, á,ç,......你说出来。
'' . "\0" . '' . "\0" . 'u'
关于应该在哪里查看的任何想法?提前谢谢。
更多信息:
PHP version 5.3.6
。setlocale()
没有解决任何问题。default_charset
在UTF-8
中为php.ini
。mbstring.internal_encoding
设置为UTF-8
中的php.ini
。mbstring.func_overload = 0
。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的回答)。
答案 0 :(得分:6)
我建议你验证你遇到问题的PHP二进制文件。检查编译器标志及其使用的库。
通常PHP内部使用二进制字符串,这意味着像ucfirst
这样的函数逐字节工作,只支持你的语言环境支持(如果配置的话)。请参阅Details of the String TypeDocs。
$ php -r "echo ucfirst('ñu');"
返回
?u
这是有道理的,ñ
是
LATIN SMALL LETTER N WITH TILDE (U+00F1) UTF8: \xC3\xB1
您配置了一些区域设置,使PHP将\xC3
更改为其他内容,打破UTF-8字节序列并使shell显示� replacement characterWikipedia。
我建议如果你真的想分析这些问题,你应该从hexdumps开始,然后在shell和其他地方显示内容。
知道你可以明确定义二进制字符串b"string"
(这是向前兼容性,你已经启用了一些编译标志,并且你正在进行unicode实验吗?),而且你也可以按字面意思写字符串,这里是hex-way for UTF-8:
$ php -r "echo ucfirst(b\"\\xC3\\xB1u\");"
还有更多可以发挥作用的设置,我开始列出an answer to Preparing PHP application to use with UTF-8中的一些点。
多字节ucfirst
变体的示例:
/**
* multibyte ucfirst
*
* @param string $str
* @param string|null $encoding (optional)
* @return string
*/
function mb_ucfirst($str, $encoding = NULL)
{
$first = mb_substr($str, 0, 1, $encoding);
$rest = mb_substr($str, 1, strlen($str), $encoding);
return mb_strtoupper($first, $encoding) . $rest;
}
答案 1 :(得分:0)
在php中尝试强制utf-8:
<? ini_set( 'default_charset', 'UTF-8' ); ?>
在任何页面/模板的顶部(第一行代码)中。它主要帮助我解决我的特殊角色。不确定它对你有帮助,试试吧。
答案 2 :(得分:0)
可能所有服务器都处于良好状态。在其中一条评论中,您说过只有ucfirst()和var_export()问题。根据这些回复,您可能会看到此SOQ。使用多字节字符串时,大多数php字符串函数将无法正常工作。这就是为什么php有separate set of functions来处理它们的原因。
This可能会有所帮助
答案 3 :(得分:0)
我通常会将utf8_encode('ñu')
用于所有法语字符
答案 4 :(得分:0)
phpunit测试正在添加到https://gist.github.com/68f5781a83a8986b9d30 - 我们可以建立一个更好的单元测试套件,以便我们可以找出预期的输出应该是什么?