Skip to content

Commit 8a28528

Browse files
committed
[cookbook][console] Filling out the console cookbook article
1 parent 5d8bed9 commit 8a28528

File tree

1 file changed

+136
-39
lines changed

1 file changed

+136
-39
lines changed

cookbook/console.rst

Lines changed: 136 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
How to Create Console/Command-Line Commands
22
===========================================
33

4-
Symfony2 ships with a console component. The framework offers a simple convention
5-
that allows you to register your own console commands for any recurring task,
6-
cronjobs, imports or other batch-jobs.
4+
Symfony2 ships with a console component, which allows you to create command-line
5+
tasks inside a rich and powerful framework. Your console commands can be used
6+
for any recurring task, such as cronjobs, imports or other batch jobs.
77

8-
To make the console commands available automatically with Symfony2 you have
9-
to create a ``Command`` directory inside your bundle and create a php file
10-
suffixed with ``Command.php`` for each task that you want to provide. If
11-
we want to to extend the HelloBundle to greet us from the command line as
12-
well we get this simple block of necessary code:
8+
Creating a Basic Command
9+
------------------------
1310

14-
.. code-block: php
11+
To make the console commands available automatically with Symfony2, create
12+
a ``Command`` directory inside your bundle and create a php file suffixed
13+
with ``Command.php`` for each task that you want to provide. For example,
14+
if you want to extend the ``AcmeDemoBundle`` (available in the Symfony Standard
15+
Edition) to greet us from the command line, create ``GreetCommand.php`` and
16+
add the following to it:
1517

16-
<?php
17-
// lib/Acme/DemoBundle/Command/GreetCommand.php
18+
.. code-block:: php
19+
20+
// src/Acme/DemoBundle/Command/GreetCommand.php
1821
namespace Acme\DemoBundle\Command;
1922
2023
use Symfony\Bundle\FrameworkBundle\Command\Command;
@@ -31,54 +34,148 @@ well we get this simple block of necessary code:
3134
->setName('demo:greet')
3235
->setDescription('Greet someone')
3336
->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?')
37+
->addOption('yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters')
3438
;
3539
}
3640
3741
protected function execute(InputInterface $input, OutputInterface $output)
3842
{
3943
$name = $input->getArgument('name');
4044
if ($name) {
41-
$output->write('Hello ' . $name);
45+
$text = 'Hello ' . $name;
4246
} else {
43-
$output->write('Hello!');
47+
$text = 'Hello';
48+
}
49+
50+
if ($input->getOption('yell')) {
51+
$text = strtoupper($text);
4452
}
53+
54+
$output->writeln($text);
4555
}
4656
}
4757
48-
We can now test the greeting by calling:
58+
Test the new console command by running the following
4959

50-
.. code-block:
60+
.. code-block:: bash
5161
52-
$> ./app/console demo:greet Fabien
53-
Hello Fabien!
62+
$ php app/console demo:greet Fabien
5463
55-
Advanced Usage
56-
--------------
64+
This will print the following to the command line::
5765

58-
Using the Dependency Injection Container
59-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66+
Hello Fabien
6067

61-
Using the Symfony\Bundle\FrameworkBundle\Command\Command as base class we
62-
also have access to the dependency injection container. As an example we
63-
could easily extend our task to be translatable:
68+
You can also use the ``--yell`` option to make everything uppercase:
6469

65-
.. code-block: php
70+
.. code-block:: bash
6671
67-
<?php
68-
// lib/Acme/DemoBundle/Command/GreetCommand.php
72+
$ php app/console demo:greet Fabien --yell
6973
70-
// ...
71-
class GreetCommand extends Command
74+
This prints::
75+
76+
HELLO FABIEN
77+
78+
Command Arguments
79+
~~~~~~~~~~~~~~~~~
80+
81+
The most interesting part of the commands are the arguments and options that
82+
you can make available. Arguments are the strings - separated by spaces - that
83+
come after the command name itself. They are ordered, and can be optional
84+
or required. For example, add an optional ``last_name`` argument to the command
85+
and make the ``name`` argument required:
86+
87+
.. code-block:: php
88+
89+
$this
90+
// ...
91+
->addArgument('name', InputArgument::REQUIRED, 'Who do you want to greet?')
92+
->addArgument('last_name', InputArgument::OPTIONAL, 'Your last name?')
93+
// ...
94+
95+
You now have access to a ``last_name`` argument in your command:
96+
97+
.. code-block:: php
98+
99+
if ($lastName = $input->getArgument('last_name')) {
100+
$text .= ' ' . $lastName;
101+
}
102+
103+
The command can now be used in either of the following ways:
104+
105+
.. code-block:: bash
106+
107+
$ php app/console demo:greet Fabien
108+
$ php app/console demo:greet Fabien Potencier
109+
110+
Command Options
111+
---------------
112+
113+
Unlike arguments, options are not ordered (meaning you can specify them in
114+
any order) and are specified with two dashes (e.g. ``--yell``). Options are
115+
*always* optional, and can be setup to accept a value (e.g. ``dir=src``)
116+
or simply as a boolean flag without a value (e.g. ``yell``).
117+
118+
.. tip::
119+
120+
It's also possible to make an option *optionally* accept a value (so
121+
that ``--yell`` or ``yell=loud`` work). Options can also be configured
122+
to accept an array of values.
123+
124+
For example, add a new option to the command that can be used to specify
125+
how many times in a row the message should be printed:
126+
127+
.. code-block:: php
128+
129+
$this
130+
// ...
131+
->addOption('iterations', null, InputOption::VALUE_REQUIRED, 'How many times should the message be printed?', 1)
132+
133+
Next, use this in the command to print the message multiple times:
134+
135+
.. code-block:: php
136+
137+
for ($i = 0; $i < $input->getOption('iterations'); $i++) {
138+
$output->writeln($text);
139+
}
140+
141+
Now, when you run the task, you can optionally specify a ``--iterations``
142+
flag:
143+
144+
.. code-block:: bash
145+
146+
$ php app/console demo:greet Fabien
147+
148+
$ php app/console demo:greet Fabien --iterations=5
149+
150+
The first example will only print once, since ``iterations`` is empty and
151+
defaults to ``1`` (the last argument of ``addOption``). The second example
152+
will print five times.
153+
154+
Recall that options don't care about their order. So, either of the following
155+
will work:
156+
157+
.. code-block:: bash
158+
159+
$ php app/console demo:greet Fabien --iterations=5 --yell
160+
$ php app/console demo:greet Fabien --yell --iterations=5
161+
162+
Advanced Usage with the Service Container
163+
-----------------------------------------
164+
165+
By Using the :class:`Symfony\\Bundle\\FrameworkBundle\\Command\\Command`
166+
as the base class for the command, you have access to the service container.
167+
In other words, you have access to use any service configured to work inside
168+
Symfony. For example, you could easily extend the task to be translatable:
169+
170+
.. code-block:: php
171+
172+
protected function execute(InputInterface $input, OutputInterface $output)
72173
{
73-
//...
74-
protected function execute(InputInterface $input, OutputInterface $output)
75-
{
76-
$name = $input->getArgument('name');
77-
$translator = $this->container->get('translator');
78-
if ($name) {
79-
$output->write($translator->trans('Hello %name%!', array('%name%' => $name)));
80-
} else {
81-
$output->write($translator->trans('Hello!'));
82-
}
174+
$name = $input->getArgument('name');
175+
$translator = $this->container->get('translator');
176+
if ($name) {
177+
$output->writeln($translator->trans('Hello %name%!', array('%name%' => $name)));
178+
} else {
179+
$output->writeln($translator->trans('Hello!'));
83180
}
84181
}

0 commit comments

Comments
 (0)