Robin Chalas
Contributed by Robin Chalas in #22734

The Symfony Console component is the second most popular Symfony component (more than 54 million downloads) and is used by the most important PHP projects, including Drupal and Magento.

Despite its great features, the Symfony Console suffered a shortcoming since day one: you must instantiate all commands to register them in the console application. The reason is that even the command name itself is defined inside a method called configure(), so you must instantiate the command class to configure it and get the command name.

In practice, this shortcoming is not a real problem for lots of applications. However, if you have lots of commands or they are very complex (because they make use of a lot of services) this can hurt performance. Moreover, if there is a single error when instantiating any of the commands, you can't run the application console, even if you are not executing the failing command.

There have been a lot of attempts to fix this problem (see #12063, #13946, #16438, #21781, etc.) In Symfony 3.4, we were finally able to fix this issue and console commands can now be lazy. This means that commands no longer need to be instantiated when running the console application, so executing any command will be a bit faster in Symfony 3.4.

In order to create a lazy-loaded command, first you must define the command as a service and then, you must add a command property to the console.command tag defining the name of the command (you can optionally add an alias attribute too):

1
2
3
4
5
6
7
8
9
app.command.complex_command:
    # ...
    tags:
        # the value of the 'command' attribute is the name of the command
        # (which is what the user needs to type in to execute it)
        - { name: console.command, command: app:my-command }

        # optionally you can define an alias for the command too
        - { name: console.command, command: app:my-command, alias: 'my-shortcut' }

And that's it! Thanks to our PSR-11 compatible containers and the dependency injection tags, this command will now be lazy loaded.

Published in #Living on the edge