我遇到了一个问题,但不知道是 PHP 还是 Windows 的命令行。当 PHP 脚本尝试将 UTF-8 字符回显到加载了 UTF-8 代码页的 cmd 时,进程会意外停止。这是一个案例:
测试1.php:
<?php
error_reporting( -1 );
echo 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', "\n";
echo "OK";
?>
测试2.php:
<?php
error_reporting( -1 );
echo 'ASCII: ABCDEFGHIJKLMNOPQRSTUVWXYZ', "\n";
echo 'UTF-8: АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', "\n";
echo 'UTF-8: АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', "\n";
echo "OK";
?>
(test1.php 和 test2.php 都保存在没有 BOM 的 UTF-8 中。)
命令提示符日志:
e:\tests>chcp 1252
Active code page: 1252
e:\tests>php -f test1.php
АБВГДЕЁЖЗРЙКЛМНОПРСТУФХЦЧШЩЫРЮЯ
OK
e:\tests>php -f test2.php
ASCII: ABCDEFGHIJKLMNOPQRSTUVWXYZ
UTF-8: АБВГДЕЁЖЗРЙКЛМНОПРСТУФХЦЧШЩЫРЮЯ
UTF-8: АБВГДЕЁЖЗРЙКЛМНОПРСТУФХЦЧШЩЫРЮЯ
OK
e:\tests>chcp 65001
Active code page: 65001
e:\tests>php -f test1.php
e:\tests>php -f test2.php
ASCII: ABCDEFGHIJKLMNOPQRSTUVWXYZ
UTF-8: АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ
e:\tests>
在 1252 模式下,所有字符都会得到回显(当然,虽然不正确)。但在 65001 (UTF-8) 模式下,test1 停在第一个字符上,而 test2 停在第二个 UTF-8 行的第一个字符上。
PHP版本是:
PHP 5.4.13 (cli) (built: Mar 15 2013 02:07:14)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
Windows 是 XP SP3。
更新:
1)如果我echo
改为:
$f = fopen( 'php://stdout', 'w' );
fwrite( $f, ... );
...
close( $f );
有用。
2)如果我重定向输出:
e:\tests>php -f test1.php > out.log
它也适用(与echo
)。
但是第一种情况有什么问题?