Laravelでカスタムなフェイカーを作成する。
メモ PHPLaravel

Laravelでカスタムなフェイカーを作成する。

2022.04.02

こんにちはjunです。Laravelはフルスタックフレームワークと言われるほど開発者に嬉しい機能が揃っています。その中でFakerと呼ばれるダミーデータを挿入する機能はよく使用します。ページングやいろんな文字を入れてみて、ビュー側やロジックなどが問題ないかを確かめることができるので、効率的な開発には必要不可欠です。

Fakerは標準で英語ですが、設定によって日本語にすることができます。FakerはPHPfakerというDevライブラリを使用しており、PHP Faker Formattersで使用できるFakerの一覧を見れます。これらのFakerはおもにFactoryで使用します。

例えば氏名、メールアドレス、文章などは以下の通りです。

$this->faker->name();
$this->faker->email();
$this->faker->realText();

上記の通りそれっぽいダミーデータを作れるのですが、時たまにアプリで必要なデータ形式のFakerがほしかったり、ランダム・特定条件のマスターのIDを出してほしい、もう少し実装するサービスに即した内容を出してほしいと言った要望がある場合はFakerを自作する必要があります。

今回はそのカスタムFakerの実装を解説したいと思います。

カスタムFakerのクラスを作成

最初にカスタムFakerのクラスを作成します。App/Faker/Custome.phpを作成します。今回はCustome.phpに実装したいFakerを作成しますが、もしクラスごとにわたい場合はCustome.phpをFakerごとのクラスに分けてください。

そしてCustome.phpは以下のように記述します。

App/Faker/Custome.php
namespace App\Faker;
use Faker\Provider\Base;

class Custome extends Base{

}

ここではFaker\Provider\Baseを継承させてください。Fakerの元ファイルもFakerメソッドを定義しているクラスで継承しています。

Faker\Provider\BaseからはrandomElements()といったランダムな配列を取得する、任意範囲の数字を取得するnumberBetween()といった便利なメソッドを使用できます。

フェイカーの書き方

例えば、食品の名前を出してくれるfoodname()というFakerを作ってみるとします。

App/Faker/Custome.php
namespace App\Faker;
use Faker\Provider\Base;

class Custome extends Base{

     protected static $foodName = ['ラーメン','パスタ','おにぎり','パン','炒飯']

     public function foodname(){
        return static::randomElement(static::$foodName);
     }
}

このような感じで、配列に静的なプロパティを作成します。そしてメソッドでそのリストからランダムで呼び出す処理を実装すれば大丈夫です。DB上にあるマスターなどを使用したい場合、DBと接続して取得してもいいと思います。

引数を設定できるので、特定の食品だけ取り出すみたいな処理を加えていいでしょう。まずカスタムFakerメソッドを実装できたので、実際に使えるようにします。

サービスプロバイダを作成

Laravelの標準のFakerはサービスプロバイダでシングルトンとして登録されています。それをオーバーライドするような処理を行っています。

App/Providers/FakerServiceProvider.php配下にサービスプロバイダを作成します。

App/Providers/FakerServiceProvider.php
namespace App\Providers;
use Faker\{Factory, Generator};
use Illuminate\Support\ServiceProvider;
use App\Faker\Custome;

class FakerServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Generator::class, function () {
            $faker = Factory::create(config('app.faker_locale'));
            $faker->addProvider(new Custome($faker));
            return $faker;
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

Factory::create(config('app.faker_locale'))としておくと、config/app.phpfaker_localeを用いて日本語化できます。そしてFakerのインスタンスにaddProvider()を使用して、作成したカスタムフェイカーを追加します。

サービスプロバイダの登録

このサービスプロバイダをconfig/app.phpproviders に追加します。

config/app.php
'providers' => [
/*
* Laravel Framework Service Providers...
*/
// 省略

/*
* Application Service Providers...
 追加
*/
    App\Providers\FakerServiceProvider::class,
],

そうするとfakerにて$this->faker->foodname()でランダムな食品名が出てきます。

すぐに検証したい場合の方法

上記のFakerはFactoryなどで使用できますが、Tinkerなどですぐに確かめたいということがあると思います。そんな時はTinkerで以下のようにFakerのインスタンスを生成して、チェックできます。なお上記のサービスプロバイダーを登録している必要があります。

php artian tinker
>> $faker = app()->make(Faker\Generator::class)
>> $faker->foodname()
=>'パスタ'
Copyright © 2021 jun. All rights reserved.