LaravelでArtisanの開始イベントと終了イベントを発行させてみた。
Laravel 4.2
app/start/artisan.php
の最後に下記のコードを追加した。
app/start/artisan.php
<?php
...
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher;
// Artisanの開始イベントと終了イベントを発行するイベントディスパッチャーの登録
$dispatcher = new SymfonyEventDispatcher();
$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
Event::fire('artisan.begin ' . $event->getCommand()->getName(), $event);
});
$dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {
Event::fire('artisan.finish ' . $event->getCommand()->getName(), $event);
});
Artisan::setDispatcher($dispatcher);
// イベント購読クラスの登録
Event::subscribe(new HogeArtisanEventHandler());
SymfonyのEventDispatcherコンポーネントを使用して、Artisanコマンドの開始時と終了時にそれぞれartisan.begin $command_name
とartisan.finish $command_name
というイベントが発行されるようにしている。
また、イベント購読クラスの登録もしている。
HogeArtisanEventHandler
クラスの実装は下記。
HogeArtisanEventHandler.php
<?php
class HogeArtisanEventHandler
{
/**
* Artisan開始イベントの処理
*/
public function onArtisanBegin($event)
{
//
}
/**
* Artisan終了イベントの処理
*/
public function onArtisanFinish($event)
{
//
}
/**
* イベント購読リスナーの登録
*
* @param Illuminate\Events\Dispatcher $events
* @return array
*/
public function subscribe($events)
{
$events->listen('artisan.begin hoge:*', 'HogeArtisanEventHandler@onArtisanBegin');
$events->listen('artisan.finish hoge:*', 'HogeArtisanEventHandler@onArtisanFinish');
}
}
イベント購読クラスはArtisanの名前空間単位で作成してみた。
このクラスではhoge:*
コマンドで発行された開始イベントと終了イベントのみリッスンしている。
開始ログや終了ログを出力したりするのに便利。
Laravel 5.3
フレームワークの機能としてCommandStarting
イベントが追加された。
しかし終了イベントがないので、終了イベントを発行したい場合には同じように自分で書く必要がある。
Laravel 5.3ではapp/Console/Kernel.php
のgetArtisan
メソッドで同じように書くことで実現できた。
Laravel 5.0〜5.4は同じ方法でできる思う(未検証)。
app/Console/Kernel.php
<?php
namespace App\Console;
use Event;
use HogeArtisanEventHandler;
use Illuminate\Console\Application as Artisan;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher;
class Kernel extends ConsoleKernel
{
...
/**
* {@inheritdoc}
*/
protected function getArtisan()
{
if (is_null($this->artisan)) {
$dispatcher = new SymfonyEventDispatcher();
$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
Event::fire('artisan.begin ' . $event->getCommand()->getName(), $event);
});
$dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {
Event::fire('artisan.finish ' . $event->getCommand()->getName(), $event);
});
$this->artisan = (new Artisan($this->app, $this->events, $this->app->version()))
->resolveCommands($this->commands);
$this->artisan->setDispatcher($dispatcher);
Event::subscribe(new HogeArtisanEventHandler());
return $this->artisan;
}
return $this->artisan;
}
}
Laravel 5.5以上
フレームワークの機能としてCommandFinished
イベントが追加されたので、自分で書く必要がなくなった。