11How 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\B undle\F rameworkBundle\C ommand\C ommand 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