PHP: UTF-8のPHPをコマンドプロンプト(CP932)で出力したい(PHP7.0以前)

注釈

コマンドプロンプトのプロパティから、フォントを「ラスター フォント」から「MS ゴシック」に変更して、
コマンド chcp 65001 を実行すれば、 UTF-8 を出力できる。

警告

日本語のフォント設定必須。
ob_start() を使用するため、 ob_flush() に注意。

簡易版

<?php
if (((PHP_OS === 'WIN32') || (PHP_OS === 'WINNT')) && (version_compare(PHP_VERSION, '7.1.0') < 0)) {
    ob_start(function($buffer) { return mb_convert_encoding($buffer, 'CP932', 'UTF-8'); });
    function mb_terminal_flush() {
        ob_flush();
    }
} else {
    function mb_terminal_flush() {}
}

echo '文字列を入力してください:';
mb_terminal_flush(); //< 標準入力待ちの前にフラッシュ
$stdin = trim(fgets(STDIN));
var_dump($stdin);

echo '数字を入力してください:';
mb_terminal_flush();
fscanf(STDIN, "%d\n", $number);
var_dump($number);

ある程度版

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
// http://php.net/manual/mbstring.supported-encodings.php
function mb_terminal_encoding()
{
    if (!extension_loaded('mbstring')) {
        return false;
    }
    if (PHP_OS === 'WIN32' || PHP_OS === 'WINNT') {
        // https://msdn.microsoft.com/en-us/goglobal/bb964653.aspx
        $codepages = array(
            '949' => 'UHC', //< Korean
            '65001' => 'UTF-8',
            '1200' => 'UTF-16',
            '1201' => 'UTF-16BE',
            '12000' => 'UTF-32',
            '12001' => 'UTF-32BE',
            '10001' => 'SJIS-mac',
        );
        $chcp = trim(strrchr(`chcp`, ' '));
        if (array_key_exists($chcp, $codepages)) {
            return $codepages[$chcp];
        }
        $encodings = mb_list_encodings();
        foreach (array('CP', 'Windows-') as $prifex) {
            $encoding = $prifex.$chcp;
            if (in_array($encoding, $encodings)) {
                return $encoding;
            }
        }
    } else {
        $locale = setlocale(LC_CTYPE, 0);
        $locale = substr($locale, strripos($locale, '.') + 1);
        $locale = strtolower(str_replace('-', '', $locale));
        foreach (mb_list_encodings() as $encoding) {
            if ($locale === strtolower(str_replace('-', '', $encoding))) {
                return $encoding;
            }
        }
    }
    return false;
}

使い方

<?php
require_once 'mb_terminal_encoding.function.php';

if (PHP_SAPI === 'cli') {
    function eol() { return PHP_EOL; }
} else {
    function eol() { return '<br />'.PHP_EOL; }
}
$terminal_encoding = mb_terminal_encoding();
$internal_encoding = 'UTF-8'; //< mb_internal_encoding();
if ($terminal_encoding !== false && $terminal_encoding !== $internal_encoding) {
    //mb_http_output($terminal_encoding);
    //ob_start('mb_output_handler');
    ob_start(
        function($buffer) use ($terminal_encoding, $internal_encoding) {
            return mb_convert_encoding($buffer, $terminal_encoding, $internal_encoding);
        }
    );
}

echo 'このPHPファイルはUTF-8ですが、CP932のコマンドプロンプトに日本語を出力します。'.eol();