The upcoming release of Symfony, 7.3, introduces invokable commands.
For me this is exciting news because more and more I believe that if a class has a single public function it should be an invokable class.
I think it reduces naming things. Now there is a lot of code that uses method names like execute or handle as the single entry point for the class.
Another reason is that with an invokable class there can't be a misunderstanding what the method is that is going to be executed.
While I was doing research how this could affect Laravel commands, which are an extension of the Symfony commands, I found out it already was possible to use __invoke, but in the documentation and using artisan make:command
the handle
method is the default.
Together with the invokable commands the CLI arguments and options can now be method arguments.
// before
class CreateUserCommand extends Command
{
protected function configure(): void
{
$this->addArgument('name', InputArgument::REQUIRED);
$this->addOption('activate', null, InputOption::VALUE_NONE);
}
}
// after
class CreateUserCommand
{
public function __invoke(
SymfonyStyle $io,
#[Argument] string $name,
#[Option] bool $activate = false,
): int
{ // code here }
}
Next to removing the need for the configure
method, it also means no more $name = $input->getArgument('name');
lines.
I never liked the Laravel command signature
property because it is text that gets parsed to the configure
method content and the name
property.
This violates the single responsibility principle.
So for me Symfony 7.3 is already a release I'm wanting to use.
I'm wondering when Laravel is going to move to the new functionality. I think the CLI arguments and options are too big of a code reduction to ignore for long.
Top comments (2)
Looks like Symfony just said, “Goodbye
configure()
, hello clean code.”Finally, we can stop arguing whether it's
handle()
orexecute()
and just let__invoke()
do its thing. Laravel better start taking notes before we all start Symfony-fying our artisan commands :)If the post gave the impression that all the commands need to change, that was not my intention. The current way will stay as is. In Symfony 7.3 there is the option to do it "new style".
In regard of Symfony-fying artisan commands.
This command works in artisan.
Once Laravel uses the Symfony 7.3 console package, the Argument and Option attributes should work as well.
So for the people that know this, creating commands is going to be easier.
The question is when that change happened, is the Laravel documentation going to address the "new style" options or is it going to stick with the current way. And will the
artisan make:command
get an option to make a more Symfony "new style" bootstrapped class.