PHPでは、テキストファイルやCSVファイルを読み込む方法がいくつかあります。
この記事では、
・ファイルを1行ずつ読み込む方法
・ファイルの内容を全て読み込む方法
・ファイルの内容を出力する方法
・ファイルの内容を配列に格納する方法
・CSVファイルを読み込む方法
という基本的な内容から、
・CSVファイルを連想配列に格納する方法
・読み込んだCSVファイルの文字化けを防ぐ方法
などの応用的な使い方に関しても解説していきます。
今回はそんなテキスト、CSVファイルを読み込む方法について、わかりやすく解説します!
ファイルを1行ずつ読み込む方法
ファイルの内容を1行ずつ読み込むには、fgets関数を使用します。
fgets関数とは
fgets関数は通常、ファイルを開くfopen関数、ファイルを閉じるfclose関数と一緒に使用します。
書き方:
string fgets ( $ファイルポインタ [, int $読み込むバイト数 ] )
引数:
第一引数に、ファイルポインタを指定します。
第二引数で読み込むバイト数を指定することもできます。指定のない場合は、行末まで読み込みます。
返り値:
読み込んだ文字列を返します。ファイルポインタから読み込むデータがもうない場合はFALSEを返します。
以下のテキストファイルを1行だけ読み込むサンプルです。
fruits.txt
apple orange banana melon pineapple
サンプルプログラム:
<?php // fruits.txtを読み込みモードで開く $fp = fopen("fruits.txt", "r"); // 1行読み込む $line = fgets($fp); echo "$line<br>"; // ファイルを閉じる fclose($fp); ?>
実行結果:
apple
「fopen(“fruits.txt”, “r”)」で、fruits.txtを読み込みモードで開きます。
fopen関数はファイルポインタを返すので、そのファイルポインタをfgets関数に渡すことで、1行読み込むことができます。
開いたファイルは、最後にfclose関数を使用して閉じます。
fgets関数を使用したファイルの読込みについては、以下の記事で詳しく解説しています。
ファイルの内容を全て読み込む方法
ファイルの内容を全て読み込むには、file_get_contents関数を使用します。
file_get_contents関数とは
file_get_contents関数は、ファイルのオープンから読み込み、ファイルのクローズまで、1つの関数で行うことができます。
書き方:
string file_get_contents ( string $ファイルパス [, bool $インクルードパス = false [, $コンテキスト [, int $オフセット値 = 0 [, int $最大バイト数 ]]]] );
引数:
第一引数には読み込むファイルのファイルパスを指定します。
第二引数にはインクルードパスを指定します。
第三引数にはコンテキストリソースを指定します。
第四引数には読み込みを開始するオフセット値を指定します。
第五引数には読み込むデータの最大バイト数を指定します。デフォルトではファイルの終端まで読み込みます。
返り値:
読み込んだデータを返します。失敗した場合はFALSEを返します。
テキストファイルを全て読み込むサンプルです。
読み込むファイルは、fgets関数で使用した「fruits.txt」を使用しています。
サンプルプログラム:
<?php $contents = file_get_contents("fruits.txt"); echo $contents; ?>
実行結果:
apple orange banana melon pineapple
改行コードも含め、ファイルの内容を全て読み込むことができています。
file_get_contents関数については、以下の記事で詳しく解説しています。
ファイルの内容を出力する方法
ファイルの内容を出力するには、readfile関数を使用します。
readfile関数とは
readfile関数は、ファイルの内容を全て読み込み、出力します。
書き方:
int readfile ( string $ファイルパス [, bool $インクルードパス = false [, resource $コンテキスト ]] )
引数:
第一引数には読み込むファイルのファイルパスを指定します。
第二引数にはインクルードパスを指定します。
第三引数にはコンテキストリソースを指定します。
返り値:
読み込んだバイト数を返します。失敗した場合はFALSEを返します。
readfile関数でファイルを読み込むサンプルです。
読み込むファイルは、fgets関数で使用した「fruits.txt」を使用しています。
サンプルプログラム:
<?php readfile("fruits.txt"); ?>
実行結果:
apple orange banana melon pineapple
echoやprintなど、文字列を出力する処理がなくても、readfile関数で出力できています。
ファイルの内容を配列に格納する方法
ファイルの内容を全て読み込み配列に格納するには、file関数を使用します。
file関数とは
file関数は、ファイルの内容を全て読み込み、1行を1つの要素とした配列に格納します。
書き方:
array file ( string $ファイルパス [, int $オプションのパラメータ = 0 [, resource $コンテキスト ]] )
引数:
第一引数には読み込むファイルのファイルパスを指定します。
第二引数にはインクルードパスを使うか、空行を飛ばすか、などのオプションを指定します。
第三引数にはコンテキストリソースを指定します。
返り値:
ファイルの内容を格納した配列を返します。
file関数でファイルを読み込むサンプルです。
読み込むファイルは、fgets関数で使用した「fruits.txt」を使用しています。
サンプルプログラム:
<?php $contents = file("fruits.txt"); // 配列を出力 print_r($contents); ?>
実行結果:
Array ( [0] => apple [1] => orange [2] => banana [3] => melon [4] => pineapple )
print_r関数は変数の値を分かりやすく出力する関数です。
ファイルの内容が配列で、1行が1要素として格納されています。
CSVファイルを読み込む方法
CSV(Comma Separated Value)ファイルとは、値をカンマ(,)で区切られた形式のファイルのことを言います。
拡張子は「.csv」でメモ帳やエクセルなどで開くことができます。
CSVファイルは以下のように値をカンマ区切りで記述します。最初の1行はデータではなく各カラムのタイトルを記述することが多いです。
##タイトル "氏名","東京都","渋谷区","郵便番号","住所1","住所2" "氏名","東京都","中央区","郵便番号","住所1","住所2" "氏名","東京都","港区","郵便番号","住所1","住所2"
CSVファイルを読み込むには、fgetcsv関数を使う方法とSplFileObjectクラスを使う方法があります。
fgetcsv関数とは
CSVファイルから1行ずつ取得して、値を取得するにはfgetcsv関数を使用します。
fgets関数と動作は似ていますが、fgetcsv関数はCSVフォーマットのファイルに対して読み込みを行い、デリミタで区切られた値ごとに配列を返します。
書き方:
array fgetcsv( $ファイルポインタ [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\" ]]]] )
引数:
第一引数にはファイルポインタを指定します。ファイルポインタは事前にfopen関数またはpopen関数などで正常にオープンされたファイルを指定する必要があります。
第二引数には行の長さを指定し、第三引数には区切り文字であるデリミタを指定します。
第四引数にはフィールド囲い込み文字を指定し、第五引数にはエスケープ文字を指定します。
以下のCSVファイルを読み込むサンプルです。
fruits.csv
fruits.csv "apple","orange","banana","melon","pineapple"
1行目にこのCSVファイルのタイトルを指定し、2行目にカンマ(,)区切りで値を設定しています。
サンプルプログラム:
<?php $file = 'fruits.csv'; //CSVファイルを読み込みモードでオープン if (($fp = fopen($file, 'r')) !== FALSE){ $row = 0; //CSVファイルを1行ずつ読み込む while (($line = fgetcsv($fp)) !== FALSE) { //タイトル行の取得 if ($row == 0){ echo 'タイトル:'.$line[0].'<br>'; $row++; continue; } echo $line[0].'<br>'; echo $line[1].'<br>'; echo $line[2].'<br>'; echo $line[3].'<br>'; echo $line[4].'<br>'; $row++; } }else{ echo $file.'の読み込みに失敗しました。'; } //ファイルをクローズ fclose($fp); ?>
実行結果:
タイトル:fruits.csv apple orange banana melon pineapple
fopen関数でファイルポインタを取得し、問題なくファイルをオープンできたらwhile文の式でfgetcsv関数を使用して、1行ずつCSVファイルを読みこんでいます。
SplFileObjectクラスとは
SplFileObjectクラスの「READ_CSV」を使用してCSVファイルを読み込むこともできます。
SplFileObjectクラスは、ファイル操作を行うためのさまざまなインターフェイスを提供しているクラスです。
書き方:
$file = new SplFileObject($ファイル名); $file->setFlags(SplFileObject::READ_CSV);
なお、fgetcsv関数よりSplFileObjectクラスでCSVファイルを読み込むほうが処理が高速でメモリ使用量が少なくて済みます。
以下にSplFileObjectクラスのREAD_CSVを使用して、CSVファイルを読み込む方法を記述します。
CSVファイルは、fgetcsv関数のサンプルと同じものを使用します。
サンプルプログラム:
<?php $filepath = 'fruits.csv'; //オブジェクトを生成する $file = new SplFileObject($filepath); //CSVファイルの読み込み $file->setFlags(SplFileObject::READ_CSV); $row = 0; //1行ずつ値を取得する foreach ($file as $line) { //空行はスキップ if (empty($line[0])){ echo 'continue'; continue; } //1行の要素数を調べる $cnt = count($line); if ($row == 0){ echo 'タイトル:'.$line[0].'<br>'; $row++; continue; } for($i = 0; $i < $cnt; $i++){ echo $line[$i].'<br>'; } } ?>
実行結果:
タイトル:fruits.csv apple orange banana melon pineapple
サンプルではファイル名を指定したSplFileObjectクラスのオブジェクトを生成し、SplFileObjectのsetFlagsを使用して引数に「SplFileObject::READ_CSV」を指定してCSVの内容を取得しています。
文字化けを防ぐ方法
CSVファイルがsjisなど日本語の文字コードで記述されている場合、CSVファイル読み込み時に文字列が文字化けしてしまうことがあります。
文字化けを防ぐためには、mb_convert_variables関数を使用して、文字列をエンコーディングする必要があります。
書き方:
mb_convert_variables(string $変換後エンコーディング, $変換前のエンコーディング, $vars);
第一引数には文字列の変換後のエンコーディングを指定し、第二引数には変換前のエンコーディングを指定します。
第三引数は、変換する変数へのリファレンスを指定します。
では実際にmb_convert_variables関数を使用して、文字エンコーディングする方法を見ていきましょう。
紹介するサンプルでは、キーと値を設定したCSVファイルを読み込んで連想配列を作成し、作成した配列に対してmb_convert_variables関数を使用しています。
使用するCSVファイルは以下となります。
fruits.csv
fruits.csv "りんご","100円" "オレンジ","80円" "バナナ","120円" "メロン","700円" "パイナップル","450円"
サンプルプログラム:
<?php $filepath = 'fruits.csv'; //オブジェクトを生成する $file = new SplFileObject($filepath); //CSVファイルの読み込み $file->setFlags(SplFileObject::READ_CSV); $row = 0; //1行ずつ値を取得する foreach ($file as $line) { //空行はスキップ if (empty($line[0])){ continue; } //1行の要素数を調べる $cnt = count($line); if ($row == 0){ echo 'タイトル:'.$line[0].'<br>'; $row++; continue; } $key[] = $line[0]; $value[] = $line[1]; } //配列を結合する $fruits = array_combine($key, $value); //エンコーディングする mb_convert_variables('UTF-8', 'SJIS-win', $fruits); print_r($fruits); ?>
実行結果:
タイトル:fruits.csv<br>Array ( [りんご] => 100円 [オレンジ] => 80円 [バナナ] => 120円 [メロン] => 700円 [パイナップル] => 450円 )
サンプルでは、SplFileObjectクラスを使用してCSVファイルの値を取得した後に、foreach文の中でキーと値の配列にCSVの値を取得しています。
キーと値の配列はループを抜けた後に、array_combine関数で配列を結合して連想配列を作成しています。
作成した連想配列に対して、mb_convert_variables関数でエンコーディングしています。
なお、CSVファイルは文字コードSJIS-winで読み込んだファイルをUTF-8に変換することを想定しています。
まとめ
今回は、テキストファイルやCSVファイルを読み込む様々な方法について解説しました。
PHPに限らず、ファイルを読み込む処理はあらゆるアプリケーションで使われていますので、この機会に覚えておきましょう。
もし、テキスト、CSVファイルを読み込む方法を忘れてしまったら、この記事を思い出してくださいね。