【问题标题】:PHP: echo'ing UTF-8 characters into Windows command linePHP:在 Windows 命令行中回显 UTF-8 字符
【发布时间】:2013-08-21 01:38:11
【问题描述】:

我遇到了一个问题,但不知道是 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 都以 UTF-8 格式保存,没有 BOM。)

命令提示符日志:

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)。

但是第一种情况有什么问题呢?

【问题讨论】:

  • 我想,问题可能出在 cmd 本身,但如果我调用 type test2.php(或任何其他 UTF-8 文件),它就可以了。

标签: php windows command-prompt


【解决方案1】:

对于 windows cyrillic 这对我有帮助(windows 7 git bash 控制台):

$text = "Юра";
echo iconv("utf-8", "cp866", $text)

【讨论】:

  • 我用了一段时间,然后写了一个批处理,大致完成php foo.php &gt; tmp &amp;&amp; type tmp所以我可以看到输出。
【解决方案2】:

您还需要更改字体。

右键单击“命令提示符”的标题栏,单击“属性”并选择 TTF 字体而不是“光栅字体”。

【讨论】:

  • 我默认设置了 Lucida Console。
【解决方案3】:

试试这个。我希望它会起作用:

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;
    }
}

【讨论】:

    【解决方案4】:

    格里格森的反应很棒!

    建议: 为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,然后您的当前值就会显示出来。

    【讨论】:

      猜你喜欢
      • 2010-12-11
      • 1970-01-01
      • 2014-04-16
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 2013-04-09
      • 2016-05-31
      相关资源
      最近更新 更多