Laravel: Hooking into Artisan Commands

Björn Kaiser
2 min readSep 28, 2020

--

For hotlaps.io I generate typed field accessors for every model field to get easier access to the data stored in a model. The accessors being typed also helps with static analysis to spot errors in my code right away and other tools help a VSCode extension I use to autocomplete code as I type.

The biggest “problem” I had though was that I always had to remember to run my custom artisan command to regenerate the files whenever I would add or remove a field from a model or when adding/removing a mod altogether — doable but not ideal.

Automate all the things!

I wanted a way to automate this. Looking through the Laravel documentation, there didn’t seem to be a way to register some code to run some other code after a command ran.

My only option would have been to write another custom Artisan command that wraps the migrate + my own command. It most certainly is a valid option but I would always have to run that specific command and make sure that arguments and options of the migrate command are in sync — meh!

If it ain’t documented, read the code!**

After digging a bit into how Artisan commands are run, I saw that after every command finishes to run, a CommandFinished event is dispatched by the framework — a perfect place for me to start!

** and then add documentation for it ;)

The Code

Now that I knew what event to listen for I only had to add the event listener to my EventServiceProvider class and things should be good to go. I added the following to the boot method of the service provider:

That’s all there is to it. Every time I run php artisan migrate or php artisan migrate:rollback my event listener will also run my custom Artisan command to re-generate the field accessor traits for all my models.

Downsides

So far the only two downsides this approach seems to have is that you can’t pass any parameters through to your Artisan command, everything needs to be hardcoded in the event listener and if your command outputs any critical information to the console it won’t be displayed either.

Both are things I can live with for my specific use-case.

Other use-cases

While the use-case I used for my example is very specific to my project and coding-style you can also do lots of other things with this. For example you could have it automatically create a test file with php artisan make:test whenever you create a new controller.

--

--