fputcsv関数の基本構文
配列をCSV形式にしてファイルに書き込みます。
区切り文字や囲み文字は変更できるのでタブで区切るTSVなどにも使えます。
逆にCSVとして読み込むfgetcsv 関数も存在します。
fputcsv ( resource $handle , array $fields , string $separator = "," , string $enclosure = '"' , string $escape_char = "\\" ) : int|false
パラメータ
型 | 名前 | 初期値 | 説明 |
resource | $handle | fopenで取得したファイルポインタを管理するリソース型のオブジェクト(ファイルハンドラやファイルストリームと同意) | |
array | fields | CSVの行にする配列 | |
string | $separator | , | フィールド区切り文字 |
string | $enclosure | ダブルクォーテーション | フィールド囲み文字 |
string | $escape | \ | エスケープ文字 |
返り値(戻り値)
型 | 説明 | 例 |
int|false | 書き込んだ文字列のサイズを返す。失敗はfalse |
fgetcsv/fputcsv関数の使い方
CSVファイルから1行ずつ読み込み・書き込みする最低限のサンプルソースコード
最低限のファイル入出力処理です。ロック制御やエラー処理は省略しています。
//=======================================================
// CSVファイルから1行読み込んで、別のファイルにコピーしていくサンプル
//=======================================================
$read_file = 'input/line-100.csv'; //読み込みファイル
$write_file = 'output/line-100.csv'; //書き込みファイル
// ファイルのオープン
$fp_r = fopen($read_file, "rb"); //読み込みファイルオープン
$fp_w = fopen($write_file, "wb"); //書き込みファイルオープン
// 読み込みファイルを1行ずつ読み込みループする
while (($fields = fgetcsv($fp_r)) != false) {
print_r($fields);
// 書き込みファイルに1行ずつファイルに書き込み
if(fputcsv($fp_w, $fields) === false){
throw new Exception("書き込みに失敗しました");
}
}
fclose($fp_r); //読み込みファイルクローズ
fclose($fp_w); //読み込みファイルクローズ
exit;
CSVファイルから1行ずつ読み込み・書き込みするサンプルソースコード【ロック&エラー処理あり完全バージョン】
こちらはロック制御やエラー処理を入れたバージョンです。
とっても長いですがWebの本番サービスで同時アクセスの可能性があるファイル処理をやろうとした場合はこれがむしろ最低限のコードになります。
//=======================================================
// CSVファイルから1行ずつ読み込んで、別のファイルにコピーしていくサンプル
//=======================================================
$start = microtime(true); //開始時間記録
$read_file = 'input/line-100.csv'; //読み込みファイル
$write_file = 'output/line-100.csv'; //書き込みファイル
try{
echo "処理開始 コピー {$read_file} => {$write_file}" . PHP_EOL;
//---------------------------------------
// 読み込みファイルのオープン&ロック処理
//---------------------------------------
$fp_r = fopen($read_file, "rb");
if(is_resource($fp_r) === true){
echo "読み込みファイルオープン成功 {$read_file}" . PHP_EOL;
if (flock($fp_r, LOCK_SH) === true) { // ファイルをロックする(共有ロック)
echo "読み込みファイルのロック成功 {$read_file}" . PHP_EOL;
}else{
throw new Exception("読み込みファイルのロック失敗 {$read_file}");
}
}else{
throw new Exception("読み込みファイルオープン失敗 {$read_file}");
}
//---------------------------------------
// 書き込みファイルのオープン&ロック処理
//---------------------------------------
$fp_w = fopen($write_file, "wb");
if(is_resource($fp_w) === true) {
echo "書き込みファイルオープン成功 {$write_file}" . PHP_EOL;
if (flock($fp_w, LOCK_EX) === true) { // ファイルをロックする(排他ロック)
echo "書き込みファイルのロック成功 {$write_file}" . PHP_EOL;
}else{
throw new Exception("書き込みファイルのロック失敗 {$write_file}");
}
}else{
throw new Exception("書き込みファイルオープン失敗 {$write_file}");
}
//---------------------------------------
// 読み込みファイルを1行ずつ読み込みループする
//---------------------------------------
echo "書き込みファイルの行数: " . count(file($write_file)) . PHP_EOL;
$line_num = 0;
while (($fields = fgetcsv($fp_r)) != false) {
++$line_num;
if($line_num%10000 === 0){ //1000行ごとに進捗出力
$now = microtime(true); //終了時間記録
echo "{$line_num}行目 " . number_format($now - $start, 4) . "秒" . PHP_EOL;
}
//---------------------------------------
// 書き込みファイルに1行ずつファイルに書き込み
//---------------------------------------
if(fputcsv($fp_w, $fields) === false){
throw new Exception("書き込みに失敗しました");
}
}
//---------------------------------------
//終了後のチェック
//---------------------------------------
if (feof($fp_r) === false) {
throw new Exception("読み込みファイルが最後まで処理されていません {$read_file}");
}
echo "書き込みファイルの行数: " . count(file($write_file)) . PHP_EOL;
echo "正常終了" . PHP_EOL;
}catch(Exception $ex) {
//---------------------------------------
// エラー処理
//---------------------------------------
echo "エラーメッセージ: " . $ex->getMessage() . PHP_EOL;
} finally { //finallyはPHP5.5より
//---------------------------------------
// 後処理。正常終了・エラー終了のいずれにしても実行
//---------------------------------------
if (is_resource($fp_r) === true) {
echo "読み込みファイルロック解除 {$read_file}" . PHP_EOL;
flock($fp_r, LOCK_UN); //ロック解除
echo "読み込みファイルクローズ {$read_file}" . PHP_EOL;
fclose($fp_r);
}
if (is_resource($fp_w) === true) {
echo "書き込みファイルロック解除 {$write_file}" . PHP_EOL;
flock($fp_w, LOCK_UN); //ロック解除
echo "書き込みファイルクローズ {$write_file}" . PHP_EOL;
fclose($fp_w);
}
}
$end = microtime(true); //終了時間記録
echo "実行にかかった時間: " . number_format($end - $start, 4) . "秒" . PHP_EOL;
exit;
関連するファイルシステム関数
ファイル入出力関数の特徴まとめ
関数 | 利用シーン | 機能 | 処理単位 | ハンドル の管理 | ロック | 速度 | メモリ節約 | 安全性 | エラー時 |
fgetc | 1文字ずつ処理する | 読み | 1文字ずつ | 別途 | 別途 | × | ○ | △自前 | 終端でfalse |
fgets | 1行ずつ処理する | 読み | 1行ずつ | 別途 | 別途 | △ | ○ | △自前 | 終端かエラー でfalse |
fread | 固定バイトごとに 処理する | 読み | 指定バイト | 別途 | 別途 | ○一括 ×分割 | ×一括 ○分割 | △自前 | エラーでfalse |
fgetcsv | CSVファイルを 1行ずつ読み込む | 読み | 1行ずつ | 別途 | 別途 | × | ○ | △自前 | エラーで0かnull |
file | ロック不要のファイル を行ごとに高速処理 &同時アクセスが少ない | 読み | データ全部 | 不要 | ロックなし | ○ | × | × | エラーでfalseや E_WARNING |
file_get_contents | ロック不要のファイル の文字列全体を高速取得 &同時アクセスが少ない | 読み | データ全部 | 不要 | ロックなし | ○ | × | × | エラーでfalseや E_WARNING |
fwrite fputs | ハンドル利用時の 書込処理全般 | 書き | 指定バイト | 別途 | 別途 | ○一括 ×分割 | ×一括 ○分割 | △自前 | エラーでfalse |
fputcsv | CSVを1行ずつ書込時 | 書き | 1行ずつ | 別途 | 別途 | × | ○ | △自前 | エラーでfalse |
file_put_contents | 1~数回だけ書込する時。 繰り返しは非常に遅い。 | 書き | データ全部 | 不要 | ロック指定可能 | ○一括 ×分割 | ×一括 ○分割 | △フラグ指定 | エラーでfalse |
コメント