stdoolwer在具有多字节字符的不同环境中的奇怪行为

时间:2017-01-12 14:44:23

标签: php utf-8 character-encoding

有5台机器。

我的是win10 64bit,php 5.6,生产服务器是最新的debian 64bit,带有php 5.6。

两台计算机都运行相同的脚本,结果相同。奇怪的是从web运行脚本和从命令行运行脚本之间的区别。

代码:

$string = chr(194) . chr(160);
var_dump($string);
var_dump(bin2hex($string));
var_dump(bin2hex(strtolower($string)));
var_dump(bin2hex(mb_strtolower($string)));

来自网络的输出:

string(2) " "
string(4) "c2a0"
string(4) "c2a0"
string(4) "c2a0"

奇怪的是,两台机器在命令行中都是一样的:

string(2) " "
string(4) "c2a0"
string(4) "e2a0"  <-- Listen this!
string(4) "c2a0"

由于某种原因,strtolower已经改变了UTF8 char的第一个字节。

我的同事有一个32位覆盆子,有PHP7,另一台服务器有64位CentO和PHP7,还有一台机器CentOs 64bit PHP 5.3.3。

但这些机器转移到c2a0的任何地方。当然,我们在任何地方都使用UTF8字符集。

导致这种情况的原因是什么?

修改

关于制作:setlocale(LC_ALL,0);

命令行:

 LC_CTYPE=en_US;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C

来自网络:

string(1) "C"

在我的本地主机上:

来自网络:

string(1) "C"

命令行:

  LC_COLLATE=C;LC_CTYPE=Hungarian_Hungary.1250;LC_MONETARY=C;LC_NUMERIC=C;LC_TIME=C

1 个答案:

答案 0 :(得分:0)

在对多字节字符串使用字符串函数之前,应该使用setlocale函数。