【Laravel】データベースと無関係のEloquentっぽいモデルを作るためのFluentクラス

著者:杉浦

【Laravel】データベースと無関係のEloquentっぽいモデルを作るためのFluentクラス

 LaravelはEloquentクラスにモデルをまとめています。Eloquentはデータベース中のテーブルに対応して扱われることを前提としたORMです。
Eloquent:利用の開始 5.8 Laravel
 webサービスにおいてモデルが欲しい時は大体、対応したテーブルを用意するのですが、時にはデータベースに関係なくモデルを作りたい時があります。具体的には別のサービスで吐き出されたファイルの中身を扱う時などです。そういった時に手製のクラスファイルを作成するのも一つの手ですが、何かしたいことが増える度に簡単なことでも一々コードを書く必要があります。何かしら継承なりuseしたいですがEloquentを継承するのは危険です。誤った呼び出し一つで存在しない場所を参照するSQLを投げるがPHP的には正しいコードが出来上がります。
 FluentはLaravelの\Illuminate\Support\Fluentに位置しているEloquentの様なプロパティ制御とjson、array扱いの要素(ArrayAccess, Arrayable, Jsonable, JsonSerializableのinterfaceを満たしている)を持った素朴なクラスです。Laravel内部で扱われているのが基本でドキュメントなしのクラスです(Laravel4とかの頃のモデルクラスっぽい?)。Fluentのコンストラクタは次の様になっており、適宜new Fluent(パラメータ配列)をすることでデータベースに関係ないEloquentライクなモデル実体を扱えます。

    /**
     * Create a new fluent instance.
     *
     * @param  array|object  $attributes
     * @return void
     */
    public function __construct($attributes = [])
    {
        foreach ($attributes as $key => $value) {
            $this->attributes[$key] = $value;
        }
    }

 継承して、そのクラスをnewしただけでインスタンスにさせたいこと、インスタンスから知りたいことの設定が完了します。クラスだけ作って何も中身がないのに自在に動く様はEloquentを彷彿とさせます。
 簡単にnewする対象を探索する処理を入れるとなお便利です。例えば次の様なstaticメソッドを生やすことでなお扱いやすくなります。

    /**
     * ファイル名で探す。
     * @param  string $filename
     * @return mixed
     */
    public static function find(string $filename)
    {
        $disk = Storage::disk('hoge_files');
        if(!$disk->exist($filename)){
            return null;
        }
        $meta_data = $disk->getMetadata($filename);
        $body_data = self::parse($disk->get($filename));
        
        return new self(array_merge($meta_data, $body_data);
    }

 バリデータを作ってコンストラクタ中で呼び出す様な仕組みを作るとプロパティに何があるのかきっちり決まり更に更に安全安心に使えます。

  • この記事いいね! (1)

著者について

杉浦 administrator