Goodby CSVってなに
メモリ効率が非常に良い、CSVをインポート/エクスポートするためのPHPライブラリです。
github : Goodby CSV
個人のアプリケーションなどでの利用ではあまりメモリ効率を考える必要がないかもしれませんが、何百万、何千万行となるような大規模なプロジェクトではCSVの処理に莫大なメモリを使用することになります。
Goodby CSVではCSVのすべての行を一気に読み込むことは無く、一行ずつコールバック関数で処理しています。
また、SJIS-win、EUC-JP、UTF-8などもサポートしているため仕様に柔軟に対応できます。
要件
・PHP 5.3.2 以上
・mbstring
インストール
Composerを利用しますので、プロジェクトフォルダ内にcomposerをインストールします。
curl -s http://getcomposer.org/installer | php
プロジェクトディレクトリのrootにcomposer.jsonを作成して、下記を記載します。
{
"require": {
"goodby/csv": "*"
}
}
インストールします。
php composer.phar install
使い方
configの設定
インポート時
use Goodby\CSV\Import\Standard\LexerConfig;
$config = new LexerConfig();
$config
->setDelimiter("\t") // Customize delimiter. Default value is comma(,)
->setEnclosure("'") // Customize enclosure. Default value is double quotation(")
->setEscape("\\") // Customize escape character. Default value is backslash(\)
->setToCharset('UTF-8') // Customize target encoding. Default value is null, no converting.
->setFromCharset('SJIS-win') // Customize CSV file encoding. Default value is null.
;
エクスポート時
use Goodby\CSV\Export\Standard\ExporterConfig;
$config = new ExporterConfig();
$config
->setDelimiter("\t") // Customize delimiter. Default value is comma(,)
->setEnclosure("'") // Customize enclosure. Default value is double quotation(")
->setEscape("\\") // Customize escape character. Default value is backslash(\)
->setToCharset('SJIS-win') // Customize file encoding. Default value is null, no converting.
->setFromCharset('UTF-8') // Customize source encoding. Default value is null.
->setFileMode(CsvFileObject::FILE_MODE_WRITE) // Customize file mode and choose either write or append. Default value is write ('w'). See fopen() php docs
;
区切り文字、括り文字、エスケープ文字、文字コード、ファイルモードの設定などが出来ます。
##使用例:PDOによるCSVデータをDBへインポート
インポートするCSV
1,tom,tomcruiseikemen@example.com
2,taro,taro@example.com
3,hanako,hanako@eample.com
hogeというDBにusersというテーブルがあるとします。
下記を実行します。
use Goodby\CSV\Import\Standard\Lexer;
use Goodby\CSV\Import\Standard\Interpreter;
use Goodby\CSV\Import\Standard\LexerConfig;
require_once("vendor/autoload.php");
//DBの設定(postgreSQLの場合)
$pdo = new PDO('pgsql:host=localhost;dbname=hoge', 'postgres', '');
//configの設定
$config = new LexerConfig();
$lexer = new Lexer($config);
$interpreter = new Interpreter();
$interpreter->addObserver(function(array $columns) use ($pdo) {
//データに処理を入れるときはこのあたりに
$stmt = $pdo->prepare('INSERT INTO users (id, name, email) VALUES (?, ?, ?)');
$stmt->execute($columns);
});
//読み込むCSVファイル
$lexer->parse('users.csv', $interpreter);
こうなります。
使用例:PDOによるDBからデータをCSVにエクスポート
下記を実行します。
use Goodby\CSV\Export\Standard\Exporter;
use Goodby\CSV\Export\Standard\ExporterConfig;
use Goodby\CSV\Export\Standard\CsvFileObject;
use Goodby\CSV\Export\Standard\Collection\PdoCollection;
use Goodby\CSV\Export\Standard\Collection\CallbackCollection;
require_once("vendor/autoload.php");
//DBの設定(postgreSQLの場合)
$pdo = new PDO('pgsql:host=localhost;dbname=hoge', 'postgres', '');
$stmt = $pdo->prepare("SELECT * FROM users");
$stmt->execute();
$collection = new CallbackCollection(new PdoCollection($stmt), function($row) {
//ここにデータの処理など
$row['name'] = strtoupper($row['name']);
return $row;
});
//configの設定 SJISで出力する
$config = new ExporterConfig();
$config->setToCharset('SJIS-win');
//エクスポート
$exporter = new Exporter($config);
$exporter->export('users_converted.csv', $collection);
下記のCSVが出力されます。
1,TOM,tomcruiseikemen@example.com
2,TARO,taro@example.com
3,HANAKO,hanako@eample.com
#まとめ
使い方が簡単。
行数がかなり多いCSVを扱う時にメモリの効率化が可能。
実際にプロジェクトで使用したりしています。
メモリ使用量の比較などはあとで時間があったらやってみます。