我遇到了一个问题,但无法判断它是PHP还是Windows的命令行。当PHP脚本尝试将UTF-8字符回显到加载了UTF-8代码页的cmd时,该过程意外停止。这是一个案例:
test1.php:
<?php
error_reporting( -1 );
echo 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ', "\n";
echo "OK";
?>
test2.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
)。
但第一种情况出了什么问题?
答案 0 :(得分:0)
您还需要更改字体。
右键单击“命令提示符”的标题栏,单击“属性”并选择TTF字体而不是“光栅字体”。
答案 1 :(得分:0)
对于windows西里尔文,这对我有帮助(Windows 7 git bash console):
$text = "Юра";
echo iconv("utf-8", "cp866", $text)
答案 2 :(得分:0)
尝试一下。我希望它能起作用:
shell_exec('chcp 866');
echo iconv('utf-8', 'cp866', $message);
或使用此改进的助手:
class ConsoleHelper
{
/**
* @var boolean
*/
private static $isEncodingSet = false;
/**
* @param string $message
* @return string
*/
public static function encodeMessage($message)
{
$isWindows = (DIRECTORY_SEPARATOR == '\\');
if ($isWindows) {
if ( ! self::$isEncodingSet) {
shell_exec('chcp 866');
self::$isEncodingSet = true;
}
$message = iconv('utf-8', 'cp866', $message);
}
return $message;
}
}
答案 3 :(得分:0)
Grigson 的反应很棒!
建议:
为 echo
创建一个包装函数,只接收可以包含非 ASCII 字符的文本并正确显示它们。
类似的东西:
<?php
function eecho($texto){
echo iconv("utf-8", "cp850", $texto);
}
$texto = "Aviação!";
echo $texto;
echo PHP_EOL;
eecho($texto);
echo PHP_EOL;
然后您可以简单地将 echo "Your text ...";
替换为 eecho ('Your text ...');
将您的 PHP 文件另存为 UTF-8(无 BOM)。
要找出操作系统对第二个参数的正确值是多少,只需在命令提示符下键入 chcp
,就会显示您的当前值。