[英]PHP: echo'ing UTF-8 characters into Windows command line
我遇到了一個問題,但不知道是 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
)。
但是第一種情況有什么問題呢?
對於 windows 西里爾文,這對我有幫助(windows 7 git bash 控制台):
$text = "Юра";
echo iconv("utf-8", "cp866", $text)
您還需要更改字體。
右鍵單擊“命令提示符”的標題欄,單擊“屬性”並選擇一種 TTF 字體而不是“光柵字體”。
試試這個。 我希望它會起作用:
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;
}
}
格里森的反應很棒!
建議:為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 ...";
by eecho ('Your text ...');
將您的 PHP 文件另存為 UTF-8(不帶 BOM)。 要找出操作系統對第二個參數的正確值是什么,只需在命令提示符下鍵入chcp
,就會顯示您的當前值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.