Skip to content

Commit a59a80c

Browse files
committed
Document invokable command
1 parent 3ae4fec commit a59a80c

19 files changed

+124
-158
lines changed

components/console/changing_default_command.rst

+4-10
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,14 @@ name to the ``setDefaultCommand()`` method::
99

1010
use Symfony\Component\Console\Attribute\AsCommand;
1111
use Symfony\Component\Console\Command\Command;
12-
use Symfony\Component\Console\Input\InputInterface;
13-
use Symfony\Component\Console\Output\OutputInterface;
12+
use Symfony\Component\Console\Style\SymfonyStyle;
1413

15-
#[AsCommand(name: 'hello:world')]
14+
#[AsCommand(name: 'hello:world', description: 'Outputs "Hello World"')]
1615
class HelloWorldCommand extends Command
1716
{
18-
protected function configure(): void
17+
public function __invoke(SymfonyStyle $io): int
1918
{
20-
$this->setDescription('Outputs "Hello World"');
21-
}
22-
23-
protected function execute(InputInterface $input, OutputInterface $output): int
24-
{
25-
$output->writeln('Hello World');
19+
$io->writeln('Hello World');
2620

2721
return Command::SUCCESS;
2822
}

components/console/events.rst

+11-15
Original file line numberDiff line numberDiff line change
@@ -209,36 +209,32 @@ method::
209209
for these constants to be available.
210210

211211
If you use the Console component inside a Symfony application, commands can
212-
handle signals themselves. To do so, implement the
213-
:class:`Symfony\\Component\\Console\\Command\\SignalableCommandInterface` and subscribe to one or more signals::
212+
handle signals themselves. To do so, subscribe to :class:`Symfony\\Component\\Console\\Event\\ConsoleSignalEvent` event::
214213

215-
// src/Command/SomeCommand.php
214+
// src/Command/MyCommand.php
216215
namespace App\Command;
217216

218-
use Symfony\Component\Console\Command\Command;
219-
use Symfony\Component\Console\Command\SignalableCommandInterface;
217+
use Symfony\Component\Console\Attribute\AsCommand;
218+
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
220219

221-
class SomeCommand extends Command implements SignalableCommandInterface
220+
#[AsCommand(name: 'app:my-command')]
221+
class MyCommand
222222
{
223223
// ...
224224

225-
public function getSubscribedSignals(): array
225+
#[AsEventListener(ConsoleSignalEvent::class)]
226+
public function handleSignal(ConsoleSignalEvent $event): void
226227
{
227-
// return here any of the constants defined by PCNTL extension
228-
return [\SIGINT, \SIGTERM];
229-
}
230-
231-
public function handleSignal(int $signal): int|false
232-
{
233-
if (\SIGINT === $signal) {
228+
// set here any of the constants defined by PCNTL extension
229+
if (in_array($event->getHandlingSignal(), [\SIGINT, \SIGTERM], true)) {
234230
// ...
235231
}
236232

237233
// ...
238234

239235
// return an integer to set the exit code, or
240236
// false to continue normal execution
241-
return 0;
237+
$event->setExitCode(0);
242238
}
243239
}
244240

components/console/helpers/cursor.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ of the output:
1313
// src/Command/MyCommand.php
1414
namespace App\Command;
1515
16-
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Attribute\AsCommand;
1717
use Symfony\Component\Console\Cursor;
18-
use Symfony\Component\Console\Input\InputInterface;
1918
use Symfony\Component\Console\Output\OutputInterface;
2019
21-
class MyCommand extends Command
20+
#[AsCommand(name: 'my-command')]
21+
class MyCommand
2222
{
2323
// ...
2424
25-
public function execute(InputInterface $input, OutputInterface $output): int
25+
public function __invoke(OutputInterface $output): int
2626
{
2727
// ...
2828

components/console/helpers/questionhelper.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ Suppose you want to confirm an action before actually executing it. Add
2727
the following to your command::
2828

2929
// ...
30+
use Symfony\Component\Console\Attribute\AsCommand;
3031
use Symfony\Component\Console\Command\Command;
3132
use Symfony\Component\Console\Input\InputInterface;
3233
use Symfony\Component\Console\Output\OutputInterface;
3334
use Symfony\Component\Console\Question\ConfirmationQuestion;
3435

35-
class YourCommand extends Command
36+
#[AsCommand(name: 'app:my-command')]
37+
class MyCommand
3638
{
37-
// ...
38-
39-
public function execute(InputInterface $input, OutputInterface $output): int
39+
public function __invoke(InputInterface $input, OutputInterface $output): int
4040
{
4141
$helper = $this->getHelper('question');
4242
$question = new ConfirmationQuestion('Continue with this action?', false);

components/console/helpers/table.rst

+7-5
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ When building a console application it may be useful to display tabular data:
2222
To display a table, use :class:`Symfony\\Component\\Console\\Helper\\Table`,
2323
set the headers, set the rows and then render the table::
2424

25+
use Symfony\Component\Console\Attribute\AsCommand;
2526
use Symfony\Component\Console\Command\Command;
2627
use Symfony\Component\Console\Helper\Table;
27-
use Symfony\Component\Console\Input\InputInterface;
2828
use Symfony\Component\Console\Output\OutputInterface;
2929
// ...
3030

31-
class SomeCommand extends Command
31+
#[AsCommand(name: 'app:my-command')]
32+
class MyCommand
3233
{
33-
public function execute(InputInterface $input, OutputInterface $output): int
34+
public function __invoke(OutputInterface $output): int
3435
{
3536
$table = new Table($output);
3637
$table
@@ -445,9 +446,10 @@ The only requirement to append rows is that the table must be rendered inside a
445446
use Symfony\Component\Console\Helper\Table;
446447
// ...
447448

448-
class SomeCommand extends Command
449+
#[AsCommand(name: 'app:my-command')]
450+
class MyCommand
449451
{
450-
public function execute(InputInterface $input, OutputInterface $output): int
452+
public function __invoke(OutputInterface $output): int
451453
{
452454
$section = $output->section();
453455
$table = new Table($section);

components/console/helpers/tree.rst

+3-8
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,17 @@ inside your console command::
2626
namespace App\Command;
2727

2828
use Symfony\Component\Console\Attribute\AsCommand;
29-
use Symfony\Component\Console\Command\Command;
3029
use Symfony\Component\Console\Helper\TreeHelper;
3130
use Symfony\Component\Console\Helper\TreeNode;
32-
use Symfony\Component\Console\Input\InputInterface;
33-
use Symfony\Component\Console\Output\OutputInterface;
3431
use Symfony\Component\Console\Style\SymfonyStyle;
3532

36-
#[AsCommand(name: 'app:some-command', description: '...')]
37-
class SomeCommand extends Command
33+
#[AsCommand(name: 'app:my-command', description: '...')]
34+
class MyCommand
3835
{
3936
// ...
4037

41-
protected function execute(InputInterface $input, OutputInterface $output): int
38+
protected function execute(SymfonyStyle $io): int
4239
{
43-
$io = new SymfonyStyle($input, $output);
44-
4540
$node = TreeNode::fromValues([
4641
'config/',
4742
'public/',

components/console/logger.rst

+2-3
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ You can rely on the logger to use this dependency inside a command::
3434
use Acme\MyDependency;
3535
use Symfony\Component\Console\Attribute\AsCommand;
3636
use Symfony\Component\Console\Command\Command;
37-
use Symfony\Component\Console\Input\InputInterface;
3837
use Symfony\Component\Console\Logger\ConsoleLogger;
3938
use Symfony\Component\Console\Output\OutputInterface;
4039

4140
#[AsCommand(
4241
name: 'my:command',
4342
description: 'Use an external dependency requiring a PSR-3 logger'
4443
)]
45-
class MyCommand extends Command
44+
class MyCommand
4645
{
47-
protected function execute(InputInterface $input, OutputInterface $output): int
46+
public function __invoke(OutputInterface $output): int
4847
{
4948
$logger = new ConsoleLogger($output);
5049

components/console/single_command_tool.rst

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,18 @@ it is possible to remove this need by declaring a single command application::
99
<?php
1010
require __DIR__.'/vendor/autoload.php';
1111

12-
use Symfony\Component\Console\Input\InputArgument;
13-
use Symfony\Component\Console\Input\InputInterface;
14-
use Symfony\Component\Console\Input\InputOption;
12+
use Symfony\Component\Console\Attribute\Argument;
13+
use Symfony\Component\Console\Attribute\Option;
1514
use Symfony\Component\Console\Output\OutputInterface;
1615
use Symfony\Component\Console\SingleCommandApplication;
1716

1817
(new SingleCommandApplication())
1918
->setName('My Super Command') // Optional
2019
->setVersion('1.0.0') // Optional
21-
->addArgument('foo', InputArgument::OPTIONAL, 'The directory')
22-
->addOption('bar', null, InputOption::VALUE_REQUIRED)
23-
->setCode(function (InputInterface $input, OutputInterface $output): int {
20+
->setCode(function (OutputInterface $output, #[Argument] string $foo = 'The directory', #[Option] string $bar = ''): int {
2421
// output arguments and options
22+
23+
return 0;
2524
})
2625
->run();
2726

components/process.rst

+7-2
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,14 @@ However, if you run the command via the Symfony ``Process`` class, PHP will use
430430
the settings defined in the ``php.ini`` file. You can solve this issue by using
431431
the :class:`Symfony\\Component\\Process\\PhpSubprocess` class to run the command::
432432

433+
use Symfony\Component\Console\Attribute\AsCommand;
434+
use Symfony\Component\Console\Style\SymfonyStyle;
433435
use Symfony\Component\Process\Process;
434436

435-
class MyCommand extends Command
437+
#[AsCommand(name: 'app:my-command')]
438+
class MyCommand
436439
{
437-
protected function execute(InputInterface $input, OutputInterface $output): int
440+
public function __invoke(SymfonyStyle $io): int
438441
{
439442
// the memory_limit (and any other config option) of this command is
440443
// the one defined in php.ini instead of the new values (optionally)
@@ -444,6 +447,8 @@ the :class:`Symfony\\Component\\Process\\PhpSubprocess` class to run the command
444447
// the memory_limit (and any other config option) of this command takes
445448
// into account the values (optionally) passed via the '-d' command option
446449
$childProcess = new PhpSubprocess(['bin/console', 'cache:pool:prune']);
450+
451+
return 0;
447452
}
448453
}
449454

console.rst

+15-17
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,19 @@ completion (by default, by pressing the Tab key).
110110
Creating a Command
111111
------------------
112112

113-
Commands are defined in classes extending
114-
:class:`Symfony\\Component\\Console\\Command\\Command`. For example, you may
115-
want a command to create a user::
113+
Commands are defined in classes, for example, you may want a command to create a user::
116114

117115
// src/Command/CreateUserCommand.php
118116
namespace App\Command;
119117

120118
use Symfony\Component\Console\Attribute\AsCommand;
121119
use Symfony\Component\Console\Command\Command;
122-
use Symfony\Component\Console\Input\InputInterface;
123-
use Symfony\Component\Console\Output\OutputInterface;
124120

125121
// the name of the command is what users type after "php bin/console"
126122
#[AsCommand(name: 'app:create-user')]
127-
class CreateUserCommand extends Command
123+
class CreateUserCommand
128124
{
129-
protected function execute(InputInterface $input, OutputInterface $output): int
125+
public function __invoke(): int
130126
{
131127
// ... put here the code to create the user
132128

@@ -147,6 +143,10 @@ want a command to create a user::
147143
}
148144
}
149145

146+
Additionally, can extend the :class:`Symfony\\Component\\Console\\Command\\Command` class to
147+
leverage advanced features like lifecycle hooks: :method:`Symfony\\Component\\Console\\Command\\Command::initialize`,
148+
:method:`Symfony\\Component\\Console\\Command\\Command::interact`, and built-in helpers.
149+
150150
Configuring the Command
151151
~~~~~~~~~~~~~~~~~~~~~~~
152152

@@ -156,18 +156,16 @@ You can optionally define a description, help message and the
156156

157157
// src/Command/CreateUserCommand.php
158158

159-
// ...
160-
class CreateUserCommand extends Command
159+
#[AsCommand(
160+
name: 'app:create-user',
161+
description: 'Creates a new user.', // the command description shown when running "php bin/console list"
162+
help: 'This command allows you to create a user...', // the command help shown when running the command with the "--help" option
163+
)]
164+
class CreateUserCommand
161165
{
162-
// ...
163-
protected function configure(): void
166+
public function __invoke(): int
164167
{
165-
$this
166-
// the command description shown when running "php bin/console list"
167-
->setDescription('Creates a new user.')
168-
// the command help shown when running the command with the "--help" option
169-
->setHelp('This command allows you to create a user...')
170-
;
168+
// ...
171169
}
172170
}
173171

console/calling_commands.rst

+4-5
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,15 @@ the returned code from the command (return value from command ``execute()``
1818
method)::
1919

2020
// ...
21+
use Symfony\Component\Console\Attribute\AsCommand;
2122
use Symfony\Component\Console\Command;
2223
use Symfony\Component\Console\Input\ArrayInput;
23-
use Symfony\Component\Console\Input\InputInterface;
2424
use Symfony\Component\Console\Output\OutputInterface;
2525

26-
class CreateUserCommand extends Command
26+
#[AsCommand(name: 'app:create-user')]
27+
class CreateUserCommand
2728
{
28-
// ...
29-
30-
protected function execute(InputInterface $input, OutputInterface $output): int
29+
public function __invoke(OutputInterface $output): int
3130
{
3231
$greetInput = new ArrayInput([
3332
// the command name is passed as first argument

console/commands_as_services.rst

+4-15
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,16 @@ For example, suppose you want to log something from within your command::
1616

1717
use Psr\Log\LoggerInterface;
1818
use Symfony\Component\Console\Attribute\AsCommand;
19-
use Symfony\Component\Console\Command\Command;
20-
use Symfony\Component\Console\Input\InputInterface;
21-
use Symfony\Component\Console\Output\OutputInterface;
2219

23-
#[AsCommand(name: 'app:sunshine')]
24-
class SunshineCommand extends Command
20+
#[AsCommand(name: 'app:sunshine', description: 'Good morning!')]
21+
class SunshineCommand
2522
{
2623
public function __construct(
2724
private LoggerInterface $logger,
2825
) {
29-
// you *must* call the parent constructor
30-
parent::__construct();
31-
}
32-
33-
protected function configure(): void
34-
{
35-
$this
36-
->setDescription('Good morning!');
3726
}
3827

39-
protected function execute(InputInterface $input, OutputInterface $output): int
28+
public function __invoke(): int
4029
{
4130
$this->logger->info('Waking up the sun');
4231
// ...
@@ -70,7 +59,7 @@ To make your command lazily loaded, either define its name using the PHP
7059
// ...
7160

7261
#[AsCommand(name: 'app:sunshine')]
73-
class SunshineCommand extends Command
62+
class SunshineCommand
7463
{
7564
// ...
7665
}

console/hide_commands.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ the ``hidden`` property of the ``AsCommand`` attribute::
1515
namespace App\Command;
1616

1717
use Symfony\Component\Console\Attribute\AsCommand;
18-
use Symfony\Component\Console\Command\Command;
1918

2019
#[AsCommand(name: 'app:legacy', hidden: true)]
21-
class LegacyCommand extends Command
20+
class LegacyCommand
2221
{
2322
// ...
2423
}

0 commit comments

Comments
 (0)