PHPには、CSVファイルを取り込むfgetcsv関数が用意されており、簡単にCSVファイルを扱えます。とはいえ、条件が合わないと文字化けすることもあり、いろいろな配慮が必要です。今回は、PHPによるCSVファイルの読み込みに使うfgetcsv関数と、その使用手順について紹介します。
目次
CSVファイルの基本
今回扱うCSVとは、「Comma Separated Value」の略で、テキストで書かれた数字や文字列などをカンマ「,」で区切ったデータ形式です。PHPにおけるCSV読み込み関数を説明する前に、CSVファイルの特徴について解説します。
CSVファイルとは何か
CSVファイルとは、テキストとして書かれた数字や文字列などをカンマ「,」で区切ったデータ形式で書かれたCSV形式のファイルです。そのため、テキストエディタで簡単にチェックでき、しかもプログラムで簡単に処理できます。
また、カンマ「,」で区切ったデータ形式は、表計算ソフトとも相性が良く、表計算ソフトから他のアプリケーションにデータを送る場合などにも、よく利用されています。
そのため、PHPで作られたWebシステムの中には、登録されたデータをCSVファイルに書き出したり、CSVファイルからデータを読み込み、一括更新する機能を用意してケースが少なくありません。
区切り文字はコンマとは限らない
CSVは、カンマ「,」で区切ったデータ形式という意味を含みますが、別の文字を使うことも可能です。例えば、商品名にコンマ「,」が使われるケースでは、カンマ「,」の代わりにタブが使われます。
なお、このような場合でも、テキストファイルで簡単にチェックでき、PHPならCSV読み込み関数と同じ関数で処理可能です。
CSVは改行までとは限らない
通常のテキストファイルは改行までが1行ですが、CSVファイルは1行の終わりが改行とは限りません。Excelなどの表計算ソフトを使ったことがある方は、1つのセルの中に、改行を含む文字を記入したことがあるでしょう。そのようなExcelファイルからCSVファイルに書き出した場合、途中に改行を含むCSVデータが作られます。
もし、PHPでCSVファイルを読み込み、そのデータをシステム内で使用する場合、データの途中に改行のあるCSVファイルにも対応しなければなりません。そして、PHPのCSV取り込み関数には、そういった点も考慮されています。ぜひ、CSV読み込み専用の関数を利用してください。
PHPでCSVを扱う関数
PHPには、CSVファイルからデータを読み込み、そのデータを活用する際に扱う関数として、fgetcsv関数が用意されています。次から、このfgetsvc()関数について解説します。
fgetcsv関数の基本
fgetcsv関数は、CSVファイルにアクセスするファイルポインタからCSVデータを1行分読み込み、そのCSVに含まれるデータを配列(array)形式で返す関数です。そのため、引数としてファイルポインタを指定しなければなりません。さらに、この関数では、最大文字数や区切り文字や、囲い込み文字も設定できます。
なお、区切り文字はデフォルトがコンマ「,」ですが、タブやアットマーク「@」などを指定できます。また、囲い込み文字とは、改行を含むテキストの範囲を示すためのキャラクターで、デフォルトはダブルクォート「”」ですが、シングルクォート「’」やバッククオート「`」などに変更可能です。
1 2 3 4 5 6 7 |
fgetcsv関数の文法 fgetcsv( ファイルポインタ ) または fgetcsv( ファイルポインタ, 最大文字数, 区切り文字, 囲い込み文字 ) |
fgetcsv関数は配列を返す
先ほど説明したように、fgetcsv()関数は、CSVに含まれるデータを配列(array)返します。例えば、下記のような1行だけのCSVファイルがあったとします。
1 2 3 |
CSVファイルの内容 1,35.68944,139.69167,Japan,Tokyo,Shinjuku |
このCSVファイルをfgetcsv関数で読み込み、配列(array)として宣言した変数に格納した場合、次のようになります。
1 |
[ 1, 35.68944, 139.69167, "Japan", "Tokyo", "Shinjuku" ] |
そして、CSVを格納した変数が$arrだった場合、次のように参照できます。v
1 2 3 4 5 6 |
echo $arr[0] // 1 echo $arr[1] // 35.68944 echo $arr[2] // 139.69167 echo $arr[3] // "Japan" echo $arr[4] // "Tokyo" echo $arr[5] // "Shinjuku" |
fgetcsv関数の書き方
下記は、CSVファイルのファイルポインタ$fhから、1行分のCSVファイルを読み込み、配列$arrに格納する例です。
1 2 3 4 5 6 7 |
<?php $fh = fopen("sample1.csv", "r"); $arr = []; $arr = fgetcsv( $fh ); ?> |
また、区切り文字がアットマーク「@」, 囲い込み文字がシングルクォート「’」で、最大文字数が1024の場合は、次のように記述します。
1 2 3 4 5 6 7 |
<$php $fh = fopen("sample2.csv", "r"); $arr = [] $arr = fgetcsv( $fh, 1024, "@", "'" ); ?> |
fgetcsv関数がエラーになったら
もし、fgetcsv関数に無効なファイルポインタを指定された場合は、nullを返します。また、ファイルの終端に達した際には、falseを返します。そのため、while文などでファイルの最後まで読み込ませる場合は、falseが出力されていることをチェックして、繰り返しを中断する書き方が可能です。
1 2 3 4 5 6 7 8 9 |
CSVファイルを最後まで読み込む例 <?php $fh = fopen("sample2.csv", "r"); $arr = []; $arr_s = []; while(($arr = fgetcsv( $fh )) !== false ) { array_push($arr_s, $arr ); } |
この例は、fgetcsv関数がCSVファイルの終端に達したらfalseを返す機能を利用し、while文でCSVを読み込み、array_pushで2次元の配列としてデータを取り込む例です。
CSV読み込み処理の例
これまでPHPでCSVファイルを扱うためのfgetcsv関数について解説してきました。次から、WebサーバーにCSVファイルをアップロードし、fgetcsv関数を使ったプログラムでデータを読み込み、それを利用するための例について解説します。
HTMLのファイルアップロード機能を使う
PHPを利用してCSVファイルをアップロードする場合、HTMLのファイルをアップロードする機能を用います。そして、Webサーバーにアップロードされたファイル名は、PHPのシステム変数に格納されているので、そのファイル名を使ってファイルポインタを作成してください。
続いて、fgetcsv()関数を使って、CSVファイルに格納されているデータを、配列に読み込みます。なお、取り込む手順は、先ほど紹介したプログラム例を参考にしてください。
そして、配列に取り込んだデータは、それぞれのデータ仕様に基づいてチェックし、問題なければデータベースに登録したり、既存のデータを書き換えなどに利用できます。
CSVファイル取り込みの例
次に、fgetcsv()関数を利用した簡単なCSVファイル取り込みプログラムを紹介します。
1 2 3 4 5 6 |
ファイルをアップロードするHTML例 <form method="post" action="csv1.php" enctype="multipart/form-data"> <input type="file" name="upfile" /><br /> <input type="submit" value="UPLOAD" /><br /> </form> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
アップロードされたCSV読み込み用PHPの例 $arr = []; $arr_s = []; if(isset($_FILES['upfile'])) { $tmpfile = $_FILES['upfile']['tmp_name']; if(is_uploaded_file($tmpfile)) { $fh = fopen($tmpfile, "r"); while(($arr = fgetcsv($fh)) !== false) { array_push($arr_s, $arr); } /* * ここにCSVファイルのデータが格納された $arr_s を利用する処理を記述 */ } } else { echo "<p>ファイルをアップロードしてください</p><br />\n"; } ?> |
この例は、HTMLのformタグからWebサーバーにアップロードされたファイルの名称が「$_FILES[‘upfile’][‘tmp_name’]」に格納されているので、そのファイルがis_uploaded_file関数で実際にあるかどうかをチェックし、もしある場合は、fopenでそのファイルを開きます。
そして、そのファイルポインタ$fhを、fgetcsv関数に指定し、1行分を配列(array)変数$arrに読み込みます。さらに、それをファイルの末尾まで繰り返し、1行分を読み込んだ配列(array)を、array_pushで2次元の配列(array)の変数$arr_sに追加しています。
CSV読み込み処理作成の注意点
CSV読み込み処理で注意してほしい点は、文字コードへの対応です。例えば、表計算ソフトでCSVを作成した場合、Excelから出力したCSVの文字コードはSJSです。しかし、GoogleスプレッドシートからダウンロードしたCSVファイルの文字コードはUTF-8であり、文字コードが違います。
PHPやデータベースなど、Webシステムを構成するアプリケーションには文字コードが決まっており、それに合わない文字コードの文字が使われると文字化けします。そのため、Webシステムに合わない文字コードのCSVを利用する場合は、事前に変換しなければなりません。
このようにCSVファイルの取り込み機能を作る場合は、文字コードに関する注意書きをアップロードするWebページに掲示するか、変換する仕組みを実装するなどの工夫が必要です。
まとめ
これまで説明したように、PHPでCSV読み込み、そのデータをシステム内で利用するためには、fgetcsv関数を利用します。CSVファイルは、ただのテキストファイルではありません。ルールに沿った方法で読み込みできないと、正しくデータが取得できないこともあります。
もし、PHPを利用したシステムでCSVファイル読み込み処理を作る場合は、fgetcsv関数を利用してください。