【Laravel】ArtisanコマンドでServiceクラスを作成する
Skrumエンジニアの木原です。
Laravelでコントローラファイルやモデルファイルを作成するときに下記のArtisanコマンドをよく使っているかと思います。php artisan make:controller HogeController
php artisan make:model HogeModel
弊社ではサービスクラスやリポジトリパターンを採用していますが、これらのファイル作成用コマンドはLaravelでは準備されていないので色々と不便さを感じていました。コピペすると修正漏れがあったり、ファイル名とクラス名が一致していなかったり、単純に作業が面倒だったり…そう感じていた方が多いのではないでしょうか。
そこで開発効率を良くするために、Service、Repositoryを作成するmakeコマンドを作成することにしました。今回はServiceクラスを作成するmakeコマンドの実装内容を紹介します。
まずはコマンドを作成
$ php artisan make:command CreateService
使用感はLaravelのコントローラーやモデル作成と同じにしたいということで以下のように記載。
protected $signature = 'make:service {serviceClassName}';
protected $description = 'Create a new service class';
すると以下で実行可能になります。
$ php artisan make:service HogeService
中括弧部分で引数を受け付けられます。これで他のartisanコマンドと使用感は遜色ないかと。
そして以下のように実装しました。
/**
* @const string service dir path
*/
public const SERVICES_PATH = 'app/Services/';
/**
* @var string
*/
private $className;
/**
* @var string
*/
private $serviceFileName;
{-- 一部省略 --}
public function handle()
{
$this->className = $this->argument('serviceClassName');
if (!$this->className) {
$this->error('Service Class Name invalid');
return;
}
$this->serviceFileName = self::SERVICES_PATH . $this->className . '.php';
if ($this->isExistFiles()) {
$this->error('Service already exist');
return;
}
$this->createServiceFile();
$this->info('Service created successfully');
}
/**
* Create Service File.
*/
private function createServiceFile(): void
{
$content = "<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Services;\n\nclass {$this->className} extends BaseService\n{\n}\n";
file_put_contents($this->serviceFileName, $content);
}
/**
* Check if the same file exists.
* @return bool
*/
private function isExistFiles(): bool
{
return file_exists($this->serviceFileName);
}
という手順になっています。入力値の検証時にinfoやerrorメソッドで色付きのメッセージを表記できるのでわかりやすいですね。
実際に作成されるファイルは以下になります。
<?php
declare(strict_types=1);
namespace App\Services;
class HogeService extends BaseService
{
}
いかがでしたでしょうか。
作成されるServiceクラスは文字列で記載しているため、各々でカスタマイズ可能です。また、mkdirで再起的にディレクトリを作成するようにするとより実用性が増すのではないでしょうか。弊社ではServiceクラスの他、Repository, Interfaceとディレクトリをまとめて作成するコマンドも実装済みです。
是非参考にしてみてください。