Laravelを使用していると、「Serviceクラスをどのように作成すれば良いのか?」や「コントローラが肥大化してきたけど、どうすればスリムにできるのか?」といった疑問や悩みを抱えることがあります。
LaravelにはデフォルトでControllerやViewのディレクトリは用意されていますが、他の多くのフレームワークにあるようなServiceディレクトリは存在しません。
このため、多くの開発者が処理の大部分をコントローラに記述してしまい、結果として「Fat Controller(ファットコントローラー)」という問題点が生じてしまいます。
この問題を解消するための一つの方法が、Serviceクラスの導入です。
この記事では、Serviceディレクトリの作成から、Serviceクラスの活用方法までを、具体的なサンプルコードを交えて詳しく解説します。
コントローラの肥大化を防ぎ、より効率的なコードを目指しましょう。
開発環境
今回の内容はPHPのバージョンやLaravelのバージョンに左右されることは無い想定ですが、念の為 動作確認した際のバージョンを記載します。
- PHP 7.4.2
- Laravel Framework 6.13.1
Serviceクラスを追加する流れ
Serviceクラスを追加する際にはクラスファイルを作成する以外に、LaravelにServiceクラスを利用するための設定が必要です。
今回はそこも含めて解説をしていきます。
- Servicesのディレクトリを作成
- Serviceクラスを作成
- AppServiceProviderに追記
- config.phpにAliasを追加
Serviceディレクトリの作成
初めてServiceクラスを作成する際には、ディレクトリが存在しないと思うので Services ディレクトリを作成しましょう。
作成場所はappディレクトリの中で、ConsoleやHttpと同じ階層に作成をします。
Console
$ mkdir app/Services
作成後は下記のようなディレクトリ構成になればOKです。
本記事ではコマンドを入力してディレクトリの作成を行っていますが、Visual Studio CodeやPHPStormなどのIDE・エディタを活用している場合はそちら経由で作成しても問題ありません。
Serviceクラスを作成
ディレクトリを作成したら、次にServicesディレクトリに作成したいクラスを追加しましょう。
今回は例としてUserServiceを作成します。
Services/UserService.php
<?php
class UserService {
public function hoge()
{
echo "UserService hoge";
}
}
今回は例としてUserServiceにhogeメソッドを定義しました。
AppServiceProviderに追記
ここまでの内容でControllerやCommandなどからServiceクラスを呼び出すことは既に可能になっています。
しかし作成したServiceのクラスを他のクラスに対して依存注入(Dependency Injection)したい場合は、サービスプロバイダーを活用しサービスコンテナに登録しておく必要があります。
サービスコンテナに登録するための記述はAppServiceProvider.phpのregisterメソッドにて行います。
app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind('App\Services\UserService'); // 追記
}
Facadeを作成してAliasを追加する
作成したServiceを呼び出す際に毎回 App\Services\UserService を記述したり、 use App\Services\UserService の様に記述するのは面倒だという人もいると思います。
そんな方はFacade(ファサード)クラスを作成し、Alias(エイリアス)を追加するのがおすすめです。
- Facadesディレクトリを作成
- Serviceクラス用のFacadeファイルを作成
- Providerを作成
- config/app.phpにAliasを追記
Facadesディレクトリを作成
Servicesディレクトリと同様に、初めてFacadeクラスを追加する際にはディレクトリが存在しません。
そこでServiceクラスと同様の手順でFacadesディレクトリを作成しましょう
Console
$ mkdir app/Facades
Facadeファイルを作成
ディレクトリの作成が完了したら、次はService用のFacadeファイルを新規で作成していきます。
app/Facades/UserService.php
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class UserService extends Facade
{
protected static function getFacadeAccessor() {
return 'UserService';
}
}
クラス名とreturnする値は追加したServiceの名前と一致するようにしておきましょう。
Providerを作成する
続いてProviderを作成していきます。
Providerのスケルトンはphp artisanコマンドで作成出来るので活用していきましょう。
Console
$ php artisan make:provider UserServiceProvider
ファイルの作成が完了すると app/Providers/UserServiceProvider.php が作成されるので中身を編集していきます。
app/Providers/UserServiceProvider.php
public function register()
{
$this->app->bind(
'UserService', // キー名
'App\Services\UserService' // クラス名
);
}
UserServiceProvider.php の registerの中身を上記の様に変更しましょう。
config/app.phpにAliasを追記
Facadeの追加まで終わったら最後に、 config/app.php にエイリアスを貼っていきます
config/app.php
'providers' => [
// 略
App\Providers\UserServiceProvider::class,
],
'aliases' => [
// 略
'View' => Illuminate\Support\Facades\View::class,
'UserService' => App\Facades\UserService::class,
],
上記のコードを追加後は、useを記載しなくてもControllerなどで UserService::hoge();の様に記述することが出来るようになります。
Serviceディレクトリは作成するべき
今回の記事ではLaravelでServiceディレクトリを追加する流れを解説してきました。
これは完全に個人的な意見ですが、Servicesディレクトリは出来る限り最初のうちに作っておくべきだと考えています。
もちろん命名は必ずしも Services である必要はありませんが、この様なデータ取得のロジックなどを記述する場所がないとコントローラーが間違いなく肥大化していきます。
効率よく開発を行うためにも適切なコードをServiceに配置して健全な開発ライフを送っていきましょう。
どこでも食っていけるWeb人間になれる【Web食いオンラインスクール】