PHP fputcsvで出力するとダブルクォーテーションで括られる

PHP のfputcsvは配列データをCSVファイルへ出力する際に自動でエスケープ処理もしてくれるので便利ですが、エンコーディングを UTF-8 から Shift-JIS へ変換して出力すると、文字列が予期せずダブルクォーテーションで括られる場合があります。

<?php
function convertEnc($arg) {
    if (is_array($arg)) {
        return array_map('convertEnc', $arg);
    } else {
        return mb_convert_encoding($arg, "SJIS-win", "UTF-8");
    }
}

$array = array(
              "あ"
             ," "
             ,"\r\n"
             ,"ソ"
             ,"十"
);
$fp = fopen("php://stdout", "w");

// UTF-8 のまま出力
fputcsv($fp, $array);

// Shift-JIS に変換して出力
//fputcsv($fp, convertEnc($array));

fclose($fp);
?>

// UTF-8 出力結果
UTF-8 のままで出力すると改行コードだけがダブルクォーテーションで囲まれます。

あ," ","
",ソ,十

// Shift-JIS 出力結果
Shift-JIS へ出力すると「ソ」、「十」もダブルクォーテーションで囲まれてしまいます。

あ," ","
","ソ","十"

「ソ」、「十」は Shift-JIS では、れぞれ「0x8F5C」、「0x835C」で 0x5C はバックスラッシュ、バックスラッシュはエスケープ文字扱いなのでダブルクォーテーションで囲まれるようです。

参考:
https://github.com/php/php-src/blob/master/ext/standard/file.c

		/* enclose a field that contains a delimiter, an enclosure character, or a newline */
		if (FPUTCSV_FLD_CHK(delimiter) ||
			FPUTCSV_FLD_CHK(enclosure) ||
			FPUTCSV_FLD_CHK(escape_char) ||
			FPUTCSV_FLD_CHK('\n') ||
			FPUTCSV_FLD_CHK('\r') ||
			FPUTCSV_FLD_CHK('\t') ||
			FPUTCSV_FLD_CHK(' ')
		) {

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください