Ввод консоли (аргументы и опции)

Наиболее интересной частью команд являются аргументы и опции, которые вы можете сделать доступными. Эти аргументы и опции позволяют вам передавать динамическую информацию из терминала в команду.

Использование аргументов команд

Аргументы - это строки, разделённые пробелами, которые идут после самого имени команды. Они упорядочены и могут быть обязательными или необязательными. Например, чтобы добавить необязательный аргумент last_name в команду и сделать аргумент name обязательным:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// ...
use Symfony\Component\Console\Input\InputArgument;

class GreetCommand extends Command
{
    // ...

    protected function configure()
    {
        $this
            // ...
            ->addArgument('name', InputArgument::REQUIRED, 'Who do you want to greet?')
            ->addArgument('last_name', InputArgument::OPTIONAL, 'Your last name?')
        ;
    }
}

Теперь у вас есть доступ к аргументу last_name в вашей команде:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// ...
class GreetCommand extends Command
{
    // ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $text = 'Hi '.$input->getArgument('name');

        $lastName = $input->getArgument('last_name');
        if ($lastName) {
            $text .= ' '.$lastName;
        }

        $output->writeln($text.'!');
    }
}

Теперь команда может быть использована любым из следующих способов:

1
2
3
4
5
$ php bin/console app:greet Fabien
Привет, Фабиен!

$ php bin/console app:greet Fabien Potencier
Привет, Фабиен Потенсье!

Также возможно позволить аргументу использовать список значений (представьте, что вы хотите поздороваться со всеми вашими друзьями). Только последний аргумент может быть списком:

1
2
3
4
5
6
7
$this
    // ...
    ->addArgument(
        'names',
        InputArgument::IS_ARRAY,
        'С кем вы хотите поздороваться (разделите несколько имён пробелом)?'
    );

Чтобы использовать это, просто укажите столько имён, сколько хотите:

1
$ php bin/console app:greet Fabien Ryan Bernhard

Вы можете получить доступ к аргументу names, как к массиву:

1
2
3
4
$names = $input->getArgument('names');
if (count($names) > 0) {
    $text .= ' '.implode(', ', $names);
}

Существует три варианта аргументов, которые вы можете использовать:

InputArgument::REQUIRED
Аргумент обязателен. Команда не будет выполнена, если этого аргумента нет;
InputArgument::OPTIONAL
Аргумент необязателен и поэтому может быть опущен;
InputArgument::IS_ARRAY
Аргумент может содержать любое количество значений. По этой причине, он может быть использован в конце списка аргументов.

Вы можете комбинировать IS_ARRAY с REQUIRED и OPTIONAL таким образом:

1
2
3
4
5
6
7
$this
    // ...
    ->addArgument(
        'names',
        InputArgument::IS_ARRAY | InputArgument::REQUIRED,
        'С кем вы хотите поздороваться (разделите несколько имён пробелом)?'
    );

Использование опций команд

В отличие от аргументов, опции не упорядочены (то есть вы можете указывать их в любом порядке) и указываются с двумя дефисами (например, --yell). Опции всегда необязательны, и могут быть настроены так, чтобы принимать значение (например, --dir=src) или просто как булев флажок без значения (например, --yell).

К примеру, добавьте новую опцию к команде, которая может быть использована для указания того, сколько раз подряд должно быть напечатано сообщение:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ...
use Symfony\Component\Console\Input\InputOption;

$this
    // ...
    ->addOption(
        'iterations',
        null,
        InputOption::VALUE_REQUIRED,
        'Сколько раз должно быть напечатано сообщение?',
        1
    );

Далее, используйте это в команде, чтобы напечатать сообщение несколько раз:

1
2
3
for ($i = 0; $i < $input->getOption('iterations'); $i++) {
    $output->writeln($text);
}

Теперь, когда вы выполняете команду, вы можете по желанию указать флажок --iterations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# итерация не предоставлена (--iterations), используется значение по умолчанию (1)
$ php bin/console app:greet Fabien
Привет, Фабиен!

$ php bin/console app:greet Fabien --iterations=5
Привет, Фабиен
Привет, Фабиен
Привет, Фабиен
Привет, Фабиен
Привет, Фабиен
Привет, Фабиен

# порядок опций неважен
$ php bin/console app:greet Fabien --iterations=5 --yell
$ php bin/console app:greet Fabien --yell --iterations=5
$ php bin/console app:greet --yell --iterations=5 Fabien

Tip

Вы также можете объявить шорткат из одной буквы, который вы можете вызвать с помощью одного дефиса, например, -i:

1
2
3
4
5
6
7
8
9
$this
    // ...
    ->addOption(
        'iterations',
        'i',
        InputOption::VALUE_REQUIRED,
        'Сколько раз должно быть напечатано сообщение?',
        1
    );

Существует четыре варианта опций, которые вы можете использовать:

InputOption::VALUE_IS_ARRAY
Эта опция принимает несколько значений (например, --dir=/foo --dir=/bar);
InputOption::VALUE_NONE
Не принимает ввод для этой опции (например, --yell);
InputOption::VALUE_REQUIRED
Это значение обязательно (например, --iterations=5), но сама опция всё ещё необязательна;
InputOption::VALUE_OPTIONAL
Эта опция может иметь или не иметь значения (например, --yell или --yell=loud).

Вы можете комбинировать VALUE_IS_ARRAY с VALUE_REQUIRED или VALUE_OPTIONAL таким образом:

1
2
3
4
5
6
7
8
9
$this
    // ...
    ->addOption(
        'colors',
        null,
        InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
        'Какие цвета вам нравятся?',
        array('blue', 'red')
    );

Tip

Ничто не запрещает вам создать команду с опцией, которая необязательно принимает значение. Однако, не существует способа определить, когда опция была использована без значения (command --language) или когда она не была использована вообще (command). В обоих случаях, полученное для опции значение будет null.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.