はじめに
CSV形式でダミーデータを大量に作りたい時ってありますよね。
数字の採番であれば、エクセルでさくっと作れますが、氏名とか郵便番号とかのダミーデータに作りたい場合って、結構大変ですよね。。
今日は、LaravelのFactoryで使われているFakerというライブラリを使って、さくっとダミーデータを作成しましょう!ってお話です。
使用技術
PHP >= 5.3.3
composer
faker
ソースコード
試したい人向け
git clone https://github.com/westhouseK/csv-generator.git
cd csv-generator
composer install
php index.php
実装
メインルーチン
$csv = new Csv(new SplFileObject('test.csv', 'w'));
// 任意でヘッダーをセット
$header = ['name', 'tel', 'mail', 'birthday'];
// 生成したいレコード数
$records = 10;
// ヘッダーを先に書き込む
$csv->set_header($header)->create_header();
// ダミーデータを作成🐹
$csv->set_records($records)->create_test_data(new MyFaker());
Csv
インタスンスにSplFileObject
をインジェクションしています。PHPでCSVを扱うならSplFileObjectが手軽でおすすめです!
出力したいCSVのヘッダーを任意で生成することが可能です。
Csvクラス
class Csv {
// ファイル操作のインスタンス
private object $file_object;
// csvのヘッダー
private array $header = [];
// 生成したいレコード数
private int $records = 0;
public function __construct(object $file_object) {
$this->file_object = $file_object;
}
// ヘッダーをセットする
public function set_header(array $header): object {
$this->header = $header;
return $this;
}
// レコード数をセットする
public function set_records(int $records): object {
$this->records = $records;
return $this;
}
// ヘッダーを保存する
public function create_header(): void {
$this->file_object->fputcsv($this->header);
}
// コンテンツを保存する
public function create_test_data(object $creater) {
for($i = 0; $i < $this->records; $i++) {
$contents = [];
$contents[] = $creater->create_name(); // (1)
$contents[] = $creater->create_phone_number();
$contents[] = $creater->create_email();
$contents[] = $creater->create_date();
$this->file_object->fputcsv($contents);
}
}
}
$creater
はFakerのインスタンスです。(1)
で直接fakerを呼び出していないのは、CSVクラスにfakerを依存させたくなかったからです。他のダミーデータ作成ライブラリを使いたくなった時に、インジェクションした方が汎用的なクラスとなるわけです。
/**
* fakerをラップするクラス
*/
class MyFaker {
// fakerのインスタンス
private object $faker;
public function __construct() {
$this->faker = Faker\Factory::create();
}
// 名前を生成する
public function create_name(): string {
return $this->faker->name;
}
// 電話番号を生成する
public function create_phone_number() {
return $this->faker->phoneNumber;
}
// メールを生成する
public function create_email() {
return $this->faker->email;
}
// 日付を生成する
public function create_date() {
return $this->faker->date($format='Y-m-d',$max='now');
}
}
上記に、Fakerの関数をラップするようにしてあげると、自分の好きなように追加することが可能です。
出力結果
以下のような、test.csvが出力されます。
name,tel,mail,birthday
"Dr. Mariano Dickinson II",1-171-037-2947,wolf.maureen@gmail.com,1993-10-31
"Carissa Lang",(443)151-6762,jkeeling@hotmail.com,1979-01-10
"Jarrod Blick Jr.",793-175-2742x626,viva49@hotmail.com,2020-07-16
・・・
出力速度
条件
- 4列出力
- MacBook Air 2019(10.14.6), プロセッサ 1.6 GHz Intel Core i5, メモリ 8GBで実行
- php memory_limit 128M(default)
レコード数 | 実行時間(秒) |
---|---|
10 | 0.04 |
100 | 0.1 |
1000 | 0.7 |
10000 | 7〜10 |
100000 | 87〜95 |
1000000 | 1007 |
100万レコード作るのはそれなりに時間がかかるので、やらないことをおすすめします。
終わりに
オブジェクト指向を少し意識して作ってみました✌
呼び出し元がスッキリしたコードが書けるように心がけていきたいです。
SplFileObjectは遅いらしいので、fopen()
で実装した方がよかったかなと思ったり...