mirror of
https://github.com/symfony/symfony-docs.git
synced 2026-03-24 00:32:14 +01:00
Fixes #20371 Both blocks are currently rendered identically. Keeping only one of the two makes it easier to contribute. Some blocks were elevated to danger.
138 lines
4.3 KiB
ReStructuredText
138 lines
4.3 KiB
ReStructuredText
How to Define Commands as Services
|
|
==================================
|
|
|
|
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
|
|
your command classes are already registered as services. Great! This is the
|
|
recommended setup.
|
|
|
|
.. note::
|
|
|
|
You can also manually register your command as a service by configuring the service
|
|
and :doc:`tagging it </service_container/tags>` with ``console.command``.
|
|
|
|
For example, suppose you want to log something from within your command::
|
|
|
|
namespace App\Command;
|
|
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
#[AsCommand(name: 'app:sunshine')]
|
|
class SunshineCommand extends Command
|
|
{
|
|
public function __construct(
|
|
private LoggerInterface $logger,
|
|
) {
|
|
// you *must* call the parent constructor
|
|
parent::__construct();
|
|
}
|
|
|
|
protected function configure(): void
|
|
{
|
|
$this
|
|
->setDescription('Good morning!');
|
|
}
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
{
|
|
$this->logger->info('Waking up the sun');
|
|
// ...
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
}
|
|
|
|
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
|
|
the command class will automatically be registered as a service and passed the ``$logger``
|
|
argument (thanks to autowiring). In other words, you only need to create this
|
|
class and everything works automatically! You can call the ``app:sunshine``
|
|
command and start logging.
|
|
|
|
.. warning::
|
|
|
|
You *do* have access to services in ``configure()``. However, if your command is
|
|
not :ref:`lazy <console-command-service-lazy-loading>`, try to avoid doing any
|
|
work (e.g. making database queries), as that code will be run, even if you're using
|
|
the console to execute a different command.
|
|
|
|
.. _console-command-service-lazy-loading:
|
|
|
|
Lazy Loading
|
|
------------
|
|
|
|
To make your command lazily loaded, either define its name using the PHP
|
|
``AsCommand`` attribute::
|
|
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
// ...
|
|
|
|
#[AsCommand(name: 'app:sunshine')]
|
|
class SunshineCommand extends Command
|
|
{
|
|
// ...
|
|
}
|
|
|
|
Or set the ``command`` attribute on the ``console.command`` tag in your service definition:
|
|
|
|
.. configuration-block::
|
|
|
|
.. code-block:: yaml
|
|
|
|
# config/services.yaml
|
|
services:
|
|
# ...
|
|
|
|
App\Command\SunshineCommand:
|
|
tags:
|
|
- { name: 'console.command', command: 'app:sunshine' }
|
|
|
|
.. code-block:: xml
|
|
|
|
<!-- config/services.xml -->
|
|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<container xmlns="http://symfony.com/schema/dic/services"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
|
https://symfony.com/schema/dic/services/services-1.0.xsd">
|
|
|
|
<services>
|
|
<!-- ... -->
|
|
|
|
<service id="App\Command\SunshineCommand">
|
|
<tag name="console.command" command="app:sunshine"/>
|
|
</service>
|
|
</services>
|
|
</container>
|
|
|
|
.. code-block:: php
|
|
|
|
// config/services.php
|
|
use App\Command\SunshineCommand;
|
|
|
|
// ...
|
|
$container->register(SunshineCommand::class)
|
|
->addTag('console.command', ['command' => 'app:sunshine'])
|
|
;
|
|
|
|
.. note::
|
|
|
|
If the command defines aliases (using the
|
|
:method:`Symfony\\Component\\Console\\Command\\Command::getAliases` method)
|
|
you must add one ``console.command`` tag per alias.
|
|
|
|
That's it. One way or another, the ``SunshineCommand`` will be instantiated
|
|
only when the ``app:sunshine`` command is actually called.
|
|
|
|
.. note::
|
|
|
|
You don't need to call ``setName()`` for configuring the command when it is lazy.
|
|
|
|
.. warning::
|
|
|
|
Calling the ``list`` command will instantiate all commands, including lazy commands.
|
|
However, if the command is a ``Symfony\Component\Console\Command\LazyCommand``, then
|
|
the underlying command factory will not be executed.
|