サンプル・プログラムの実行例

目次
サンプル・プログラム
csv2table.php | サンプル・プログラム本体。 |
sample1.csv | サンプルCSVファイル。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.6.2 | 2025/01/19 | PHP8.4対応など |
1.6.1 | 2023/04/29 | コメントなど追記 |
1.6 | 2021/02/06 | PHP8対応 |
1.52 | 2017/07/01 | setlocaleのエラー判定、PHPバージョン表示 |
1.51 | 2014/07/20 | bug-fix:setlocale処理追加 |
プログラムの流れ

ヒアドキュメント
csv2table.php
22: // HTMLヘッダを画面表示する.
23: $encode = INTERNAL_ENCODING;
24: $title = TITLE;
25: $width = WIDTH;
26: echo <<< EOT
27: <!DOCTYPE html>
28: <html lang="ja">
29: <head>
30: <meta charset="{$encode}">
31: <title>{$title}</title>
32: <meta name="author" content="studio pahoo" />
33: <meta name="copyright" content="studio pahoo" />
34: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
35: <meta http-equiv="X-UA-Compatible" content="IE=edge">
36: <meta name="viewport" content="width={$width},user-scalable=yes" />
37: <style type="text/css">
38: table, td, th {
39: width: {$width}px;
40: border-collapse: collapse;
41: border: 1px solid black;
42: }
43: </style>
44: </head>
45: <body>
46:
47: EOT;
input type="file"タグ
csv2table.php
64: <h2>{$title} {$version}</h2>
65: <form method="post" action="{$myself}" enctype="multipart/form-data">
66: ファイル選択:<input type="file" id="file" name="file" size="80" />
67: <input type="submit" name="submit" value="変換" />
68: </form>
1つだけ注意したいのは、type="file" がHTTPサーバに送るデータは、指定されたファイルの中身も含まれているということである。もちろんバイナリ・ファイルも送ることができるので、エンコード・タイプを指定してやらなければならない。通常は、enctype="multipart/form-data"を指定する。type="file"の内容は POSTメソッド で送られ、PHP側ではスーパーグローバル変数 $_FILE で受け取ることができる。
csv2table.php
81: } else {
82: // CSVファイルが存在するか(クライアントからサーバにアップされたか)
83: if ($_FILES['file']['size'] == 0) {
84: echo 'Error! - 指定したファイルが見あたりません';
85: exit(1);
86: }
また、スーパーグローバル変数 $_FILES[名前]['tmp_name'] に、送られたファイルのサイズが格納されるので、この値が 0 だったら、ファイル指定が間違っていたとしてエラーを表示する。
CSVファイルのオープン
すでに POST されたファイルをオープンするので fopen エラーは発生しないはずだが、念のためエラーチェックを行っている。
ロケールの設定
csv2table.php
93: // CSVファイルのロケール(文字コード)を判定する.
94: $str = fgets($infp);
95: if (($enc = mb_detect_encoding($str)) == FALSE) {
96: echo 'Error! - 文字コードが判定できません';
97: exit(1);
98: }
99: // WindowsなどではFALSEでも正常に変換できるため.
100: if (setlocale(LC_ALL, 'ja_JP.' . $enc) == FALSE) {
101: $warning = '<li>Warning! - OSがロケール ' . 'ja_JP.' . $enc . ' に対応していません.</li>';
102: }
103: // 念のため読み込みポインタを先頭へ戻す.
104: fseek($infp, 0);
ロケール情報とは、言語や国・地域ごとに異なる単位、記号、日付、通貨などの表記規則をあらわす情報だ。
PHP4やWindows環境では指定しなくても大丈夫だが、それ以外の環境では関数 fgetcsv で日本語が文字化けを起こすことがある。

OSによっては、シフトJISに対応するロケールが用意されていなかったりする。
そこで、関数 setlocale の戻り値が FALSE だったら、変数 $warning に警告メッセージを記録し、最後に表示するようにした。
Linux系でロケールが用意されていない場合の対応については「PHPのfgetcsv()がsetlocaleしてもダメな時にやるべきたった一つの事」(たけまるの日記)に詳しい。
この方法でも文字化けが起きる場合は、「PHPでCSVファイルを読み込む(その2)」のプログラムをお試しいただきい。
CSVファイル読み込みと表形式への変換
csv2table.php
113: // CSVファイルを1行ずつ読み込んで,カラムに分解してTABLEタグで画面表示する.
114: while (($csv = fgetcsv($infp, 1000, $delimiter, '"', '\\')) !== FALSE) {
115: print "<tr>\n";
116: foreach ($csv as $key=>$val) {
117: // デリミタ間にデータが存在しない場合は空白出力
118: if ($val == '') {
119: $val =' ';
120: }
121: // 文字コード変換
122: $val = mb_convert_encoding($val, INTERNAL_ENCODING, 'auto');
123: echo "<td>{$val}</td>\n";
124: }
125: echo "</tr>\n";
126: }
127: echo "</table>";

fgetcsv (fopenで戻るファイル番号, 最大読み込みバイト数, 区切り文字,
フィールド囲いこみ文字, エスケープ文字)

のようにして使う。区切り文字はカンマ , がよく使われる。フィールド囲いこみ文字は、文字列として認識するときの囲み文字で、ダブルクォーテーション " がよく使われる。エスケープ文字は、区切り文字やフィールド囲いこみ文字を含むデータを扱うときの記号を指定する。PHP8.1以上では、フィールド囲いこみ文字, エスケープ文字を記述することが推奨になったので留意されたい。
戻り値は、区切り文字で区切られた部分文字列からなる配列である。ループ終了条件は、関数 fgets が失敗(ファイル・エンド)するまでである。

関数 fgets で得られた配列(表の1行に相当)を foreach で読み込み、<td> タグで囲みながら表示する。
この際、関数 mb_convert_encoding により、入力ファイルが Shift JIS, EUC-JP, UTF-8 のいずれであっても、自動的に出力エンコード(UTF-8)に変換し、文字化けが起きないようにしている。
foreach が終わったら、<tr> タグで囲む。

なお、このプログラムは、すべての行に同じ数の区切り文字が存在している――列が結合していることはない――ことを前提としている。
ただし、「デリミタの間にデータが存在しない場合、HTMLで空欄をいれたい」という要望があったので、取り出した文字が空である場合、空白文字( )を出力するようにした。

このプログラムはインターネット上のCSV形式ファイルに対しても、まったく同じ手順で表形式に変換することができる。Firefox/Chrome系ブラウザであれば、「ファイルを選択」ボタンをクリックしたときに表示されるファイルダイアログに、CSVファイルのURLを入れることで変換してくれる。
参考サイト
- PHPでCSV形式ファイルを読み込んで表にする(その2):ぱふぅ家のホームページ
- PHPのfgetcsv()がsetlocaleしてもダメな時にやるべきたった一つの事:たけまるの日記
そこで今回は、ローカルマシン上にあるCSVファイルを読み込み、HTMLの表(TABLEタグ)に変換して画面に表示するプログラムをつくる。
(2025年1月19日)PHP8.4対応など