Laravelを静的解析フレンドリにしてPhpStormで快適に開発するテクニック
Laravelから魔法を取り除いて静的解析フレンドリにして、PhpStormで快適に開発するテクニックを紹介したいと思います。静的解析フレンドリにすることは、PhpStormだけではなく、Larastanなどの静的解析ツールなどでも、より良い解析結果を返してくれるようになるかと思います。
Facadeを使用する場合にAliasを使用しない
Facadeを使用する場合にAliasを使用しないようにしましょう。PhpStormはAliasに対応していため、Facadeクラスを見つけることができません。Aliasを使用せず、namespaceをきちんと書くことでFacadeクラスを見つけることができます。
ビルトインのFacadeにはPHPDocが書かれており、Facadeのメゾットを保管することが出来ます。
例:
- \App::environment()
+ \Illuminate\Support\Facades\App::environment()
Model::queryを使用してクエリー実行する
Eloquent ORMを使用するときは、query
メソッドから開始することでメソッドを保管することができるようになります。
例:
- User::where('created_at', '<', now())->get();
+ User::query()->where('created_at', '<', now())->get();
Model::newEloquentBuilderをオーバーライドして独自QueryBuilderを定義する
ローカルスコープ(scope***
)を使用せずに、newEloquentBuilder
メソッドをオーバーライドして独自QueryBuilderを定義すると静的解析が可能になります。独自定義したQueryBuilderは、通常時と同様にModelのグローバルスコープやローカルスコープも使用することが出来ます。
例:
namespace App\Models;
use App\EloquentBuilders\BookBuilder;
use Illuminate\Database\Eloquent\Model;
/**
* @method static BookBuilder query()
*/
class Book extend Model
{
/**
* @param \Illuminate\Database\Query\Builder $query
*
* @return BookBuilder<self>
*/
public function newEloquentBuilder($query): BookBuilder
{
return new BookBuilder($query);
}
}
namespace App\EloquentBuilders;
use App\Models\Book;
use Illuminate\Database\Eloquent\Builder;
/**
* @template TModelClass of Book
* @extends Builder<TModelClass>
*/
class BookBuilder extends Builder
{
public function wherePublished(): static
{
return $this->where('published_at', '<=', now());
}
public function whereLikeTitle(string $keyword): static
{
return $this->where('title', 'LIKE', '%' . $keyword . '%');
}
}
Book::query()
->wherePublished()
->whereLikeTitle($keyword)
->orderBy('published_at', 'DESC')
->get();
Accessor/Mutatorではなくメソッドを直接使用する
Laravel 8以前のAccessor/Mutatorの書き方であるget***Attribute
/ set***Attribute
を使用する場合で、データの読み書きをする際に、Accessor/Mutatorを使用せずにメソッドを直接使用することで、静的解析することができるようになります。
例:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $appends = [
'full_name',
];
public function getFullNameAttribute(): string
{
return sprintf('%s %s', $this->first_name, $this->last_name);
}
}
- $user->full_name;
+ $user->getFullNameAttribute();
Laravel IDE Helperについて
LarastanはLaravel IDE Helperを使用しているとバグが発生することがあるようです。そのため、Larastanを使用するのであれば、Laravel IDE Helperはインストールしない方が良いかもしれません。
おわりに
newEloquentBuilder
メソッドをオーバーライドするのはお行儀が悪そうに思えますが、独自QueryBuilderを定義することによって、Repositoryパターンのように関心事を分けることができるので、静的解析関係なくおすすめです。