简体   繁体   中英

PHP: echo'ing UTF-8 characters into Windows command line

I've ran into a problem, but can't tell whether it is PHP or Windows' command line. When a PHP script tries to echo UTF-8 characters into cmd with UTF-8 codepage loaded, the process stops unexpectedly. Here is a case:

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";
?>

(Both test1.php and test2.php are saved in UTF-8 without BOM.)

The command prompt log:

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>

While in 1252 mode, all characters get echoed (although not correctly, of course). But in 65001 (UTF-8) mode test1 stalls on the very first character while test2 stalls on the first one of the second UTF-8 row.

PHP version is:

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 is XP SP3.

Update:

1) If I change echo to:

$f = fopen( 'php://stdout', 'w' );
fwrite( $f, ... );
...
close( $f );

it works.

2) If I redirect the output:

e:\tests>php -f test1.php > out.log

it also works (with echo ).

But what is wrong with the first case?

For windows cyrillic this helps me (windows 7 git bash console):

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

You need to change the font as well.

Right click the title bar of "Command Prompt", click "Properties" and select a TTF font rather than "Raster Fonts".

Try this. I hope it will work:

shell_exec('chcp 866');
echo iconv('utf-8', 'cp866', $message);

Or use this improved helper:

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

Grigson's response is great!

Suggestion: Create a wrapper function for echo , to just receive text that can contain non-ASCII characters and display them correctly. Something like:

<?php

function eecho($texto){
    echo iconv("utf-8", "cp850", $texto);
}

$texto = "Aviação!";

echo $texto;
echo PHP_EOL;
eecho($texto);
echo PHP_EOL;

Then you can simply replace echo "Your text ..."; by eecho ('Your text ...');

Save your PHP file as UTF-8 (without BOM). To find out what is your operating system's correct value for the second argument, just type chcp at the command prompt, then your current value will be displayed.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM