PHPからCSVファイルを出力する際にメモリを節約する方法
2024/07/18
MySQLよりデータを大量に取り出してCSVファイル化し、ダウンロードさせるというPHPのプログラムを作成した。今まではデータ件数が少なかったので問題なかったが今回は数十万件のデータをCSV化するというものになりメモリが足りなくなりエラーとなった。以下に対応方法をメモ。
テスト条件
使用したテーブル構造は以下の通り。
mysql> show columns from item; +--------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | key | varchar(30) | YES | | NULL | | | point | int(10) unsigned | YES | | NULL | | | created_date | datetime | YES | MUL | NULL | | +--------------+------------------+------+-----+---------+----------------+
ランダムなデータを400万件ほど突っ込んであるテーブルで今回はそこから1万件取得し、CSV化するというもの。
今までのCSV化方法
過去記事のCSV化方法だとメモリ使用量は約9MBとなった。
今回試した方法
$name = date('ymdhis'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . $name . '.csv'); $fp = fopen('php://output', 'w'); stream_filter_append($fp, 'convert.iconv.UTF-8/CP932', STREAM_FILTER_WRITE); $sql = ' SELECT * FROM item LIMIT 10000 '; $row = $mysqli->query($sql); while ($rs = $row->fetch_array(MYSQLI_ASSOC)) { fputcsv($fp, $rs); }
メモリ使用量は約2MB。4.5倍ほど改善された。
LeagueCSVライブラリを使うのも良い(2024/07/18追記)
PHPの「LeagueCSV(thephpleague / csv)」というライブラリがComposer無しで導入でき、使用方法も簡単な上に特に指定せずともメモリを節約してくれる。詳細は以下記事参照。
参考サイト
関連記事
-
フォームからCSVファイルをアップロードしてPHPの配列に格納する方法
formからcsvファイルをアップロードさせて、PHPで色々処理したかった。とり ...
-
PHPでCSVファイル出力用の関数
ここのところログ系をCSVファイル出力にするケースが多かった為、使いまわせるよう ...
-
CSVファイルを使って郵便番号から住所を抽出する
■ソース <? error_reporting(E_ALL & ~ ...
-
PHPでCSVを簡単に取り扱える「LeagueCSV(thephpleague / csv)」の利用方法
PHPでCSVファイルの書き込みや読み込みを行う際、バニラPHPで対応していたが ...
-
PHPで簡単にCSVファイルの生成
簡単にデータ並べるだけのCSVファイル生成。 file_put_contensで ...