質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

12161閲覧

csvが文字化けする

coinbura

総合スコア106

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

2クリップ

投稿2016/04/01 08:44

編集2016/04/01 09:02

以下のコードで、UTF8のcsvをPCへダウンロードして、Excelで開こうとしています。

php

1$fileName = "hoge.csv"; 2header('Content-Type: application/octet-stream'); 3header('Content-Disposition: attachment; filename='.$fileName); 4readfile($fileName); 5echo mb_convert_encoding($fileName,"SJIS", "UTF-8");

しかし、出力されたファイルはUTF8のままです。
http://qiita.com/ikemonn/items/f2bc4f9f834c989084ff
を参考にしたのですが、ちょっと古いのでしょうか。

今現在、PHPのバージョンは5.6です。

何が原因か分からず途方にくれています。
原因が分かる方おられましたらご教授いただけると幸いです。

よろしくお願いいたしますm(__)m

追記.
PHPにエラーはなく、CSVにSJISで表現できない文字はありません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/04/01 08:49

ぱっと思いつくチェック項目→ errorやwarningは出力されていませんか? SJIS表現できない文字が含まれていたりしませんか?
guest

回答4

0

ベストアンサー

PHP: readfile - Manual

説明 ¶

int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )
ファイルを読んで標準出力に書き出します。

変換しないで出力してたらそりゃUTF8のままですわ。

あと、

PHP: mb_convert_encoding - Manual

説明 ¶

string mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ] )
文字列 strの文字エンコーディングを、 オプションで指定した from_encoding から to_encoding に変換します。

mb_convert_encoding($fileName,"SJIS", "UTF-8");

↑これで変換してる文字は「hoge.csv」じゃねっすか?

投稿2016/04/01 09:11

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coinbura

2016/04/01 09:39

なるほど! 両方とも、的を得た素晴らしいご指摘! なんとか改善策を探ってみます!
guest

0

そもそもShift_JISだと表せる文字がUTF-8より減ってしまい,範囲外の文字は?に化けてしまうので,以下のようにUnicodeを取り扱えるBOMつきのCSVを用いるべきです.

【追記】

CSVにSJISで表現できない文字はありません。

ごめんなさい見てませんでした…

  • UTF-8なら 0xEF 0xBB 0xBF
  • UTF-16のLE (Little Endian)なら 0xFE 0xFF (Mac版のExcelはこれしか受け付けない)
  • UTF-16のBE (Big Endian)なら 0xFF 0xFE

Macも意識するなら真ん中のやつ1択です.

  • [[PHP] Mac版Excelと互換性のあるCSVファイルを出来るだけ効率よく作成する

](http://qiita.com/mpyw/items/2795bef3ed561f4cf4e9)

こいつをもとに今回の要件に合わせて回答を書くと

php

1<?php 2 3// バッファリングをオフにして巨大なCSVファイルも取り扱えるようにする 4// readfileやfpassthruを使うならこれをやっておかないと勿体無い 5while (ob_get_level()) ob_end_clean(); 6 7// BOM無しUTF-8のCSVファイルをオープン 8if (!$fp = @fopen('data.csv', 'rb')) { 9 // 失敗時 10 header('Content-Type: text/plain; charset=UTF-8'); 11 $error = error_get_last()['message']; 12 if (strpos($error, 'No such file or directory') !== false) { 13 http_response_code(404); 14 } elseif (strpos($error, 'Permission denied') !== false) { 15 http_response_code(403); 16 } else { 17 http_response_code(500); 18 } 19 exit($error); 20} 21 22// 読み出し時にUTF-8からUTF-16LEに変換するようにストリームフィルタを付加 23stream_filter_prepend($fp, 'convert.iconv.utf-8/utf-16le'); 24 25// ダウンロード用のHTTPヘッダを出力 26// MIMEタイプも正しく出しておいたほうが親切 27header('Content-Type: text/csv; charset=UTF-16'); 28header('Content-Disposition: attachment; filename="data.csv"'); 29 30// UTF-16(LE)のBOMを出力 31echo "\xFE\xFF"; 32 33// 続けてCSVファイルの内容をUTF-16LEで出力 34// バッファリングをオフにしていれば最も効率のいい区切りでPHPが適当に分割出力してくれる 35fpassthru($fp);

となります.ストリームフィルタを使っているので,メモリに載りきらないような巨大なCSVファイルも取り扱える上に非常に処理が高速です.

投稿2016/04/01 12:47

編集2016/04/01 12:51
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

readfile($fileName);を実行した段階でファイルが展開されるため、mb_convert_encodingをはさめないと思います。(下の例でいけるかはわかりませんが)

PHP

1$data = file_get_contents($file); 2$data = mb_convert_encoding($data, 'UTF-8', 'sjis-win');

以下参考になれば。

【PHP、文字化けせずにCSVファイルを読み込み - Qiita】
http://qiita.com/tsujimomo/items/1153d6f7f38cb1b0c263
【CSVファイルを読み取る処理で文字化けするとき | PHPプログラミングの教科書 [php1st.com]】
http://php1st.com/1899/
【PHPで読み込んだファイルの文字コードがSJISで文字化け | 広島のホームページ制作会社 株式会社GOWEB】
http://goweb.jp/blog/2011/07/05/1606/

投稿2016/04/01 09:13

kei344

総合スコア69364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coinbura

2016/04/01 09:53

具体的な例と参考サイトありがとうございます。 これとfile_put_contentsでできそうです♪
guest

0

readfile が余分です


こうですかね

//readfile($fileName); echo mb_convert_encoding(file_get_contents($fileName),"SJIS", "UTF-8");

投稿2016/04/01 09:06

編集2016/04/01 09:14
ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coinbura

2016/04/01 09:13

ご回答ありがとうございます。 早速reafileのある一文を削除してみたところ、csvの中身が「hoge.csv」となってしまいました(^^A
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問