# Symfony 控制台命令教程

> 原文： [http://zetcode.com/symfony/commands/](http://zetcode.com/symfony/commands/)

Symfony 控制台命令教程介绍了如何在 Symfony 中创建控制台命令。 我们将在控制台应用中创建几个命令。

## Symfony

Symfony 是一组可重用的 PHP 组件和一个用于 Web 项目的 PHP 框架。 Symfony 于 2005 年发布为免费软件。Symfony 的原始作者是 Fabien Potencier。 Symfony 受到 Spring 框架的极大启发。

## Symfony 控制台组件

Symfony 控制台组件使我们可以创建命令行命令。 控制台命令可用于创建 CronJob，导入，批处理作业或某些支持性任务。 Symfony 控制台命令可以在 Symfony 控制台应用或 Web 应用中使用。 在本教程中，我们将为控制台应用创建命令。

## Symfony 控制台命令示例

在以下示例中，我们使用 Symfony 控制台组件创建 Symfony 控制台应用。

```php
$ mkdir commands
$ cd commands

```

我们创建一个项目目录并找到它。

```php
$ composer require symfony/console

```

我们安装`console`包。

`composer.json`

```php
{
    "name": "Symfony command application",
    "description": 
    "This application demonstrates the usage of a Symfony command in a console application",
    "require": {
        "symfony/console": "^4.2"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src"
        }
    }
}

```

我们更新`composer.json`文件。 我们启用`App`名称空间下`src`目录中的 PHP 类的自动加载。

```php
$ composer dump-autoload -o

```

创建文件后，我们需要调用`composer dump-autoload -o`命令，该命令将创建一个将类映射到 PHP 文件的文件。

在应用中，我们将有五个命令：

*   `TimeCommand` - 显示当前日期和时间
*   `MessageCommand` - 显示来自用户输入的消息
*   `ColorCommand` - 以彩色显示消息
*   `BooksCommand` - 在表格中显示书籍列表
*   `AskNameCommand` - 交互式询问用户名

这些命令在`src/Command`目录中创建。 社区必须扩展`Symfony\Component\Console\Command`并实现其`configure()`和`execute()`方法。

之后，将命令与`add()`一起添加到`Symfony\Component\Console\Application`。

`src/Command/TimeCommand.php`

```php
<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class TimeCommand extends Command 
{
    protected function configure()
    {
        $this->setName('time')
        ->setDescription('Shows current date and time')
        ->setHelp('This command prints the current date and time');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $now = date('c');
        $message = sprintf("Current date and time: %s", $now);

        $output->writeln($message);
    }
}

```

`TimeCommand`显示当前日期和时间。

```php
protected function configure()
{
    $this->setName('time')
    ->setDescription('Shows current date and time')
    ->setHelp('This command prints the current date and time');
}

```

在`configure()`中，我们使用`setName()`设置命令的名称。 名称将显示在可用命令列表中。 我们还为命令添加了描述和帮助。

```php
protected function execute(InputInterface $input, OutputInterface $output)
{
    $now = date('c');
    $message = sprintf("Current date and time: %s", $now);

    $output->writeln($message);
}

```

`InputInterface`用于从用户获取输入，`OutputInterface`用于显示输出。 在我们的例子中，我们使用标准 ISO 格式的`date()`获取当前日期和时间，并使用`writeln()`将其输出到控制台。

`src/Command/MessageCommand.php`

```php
<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;

class MessageCommand extends Command
{
    protected function configure()
    {
        $this->setName('msg')
            ->setDescription('Prints a user provided message')
            ->setHelp('This command prints a message provided by the user')
            ->addArgument('msg', InputArgument::REQUIRED, 'Pass a message');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $message = sprintf('The message is: %s', $input->getArgument('msg'));
        $output->writeln($message);
    }
}

```

`MessageCommand`打印从用户的参数检索到的消息，并将其输出到控制台。

```php
$this->setName('msg')
    ->setDescription('Prints a user provided message')
    ->setHelp('This command prints a message provided by the user')
    ->addArgument('msg', InputArgument::REQUIRED, 'Pass a message');

```

该参数可以是必需的，也可以是可选的。 `InputArgument::REQUIRED`值使该参数成为必需参数。

```php
$message = sprintf('The message is: %s', $input->getArgument('msg'));
$output->writeln($message);

```

我们从输入中检索带有`getArgument()`的参数，然后使用`writeln()`将该参数写入控制台。

`src/Command/ColorCommand.php`

```php
<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

class ColorCommand extends Command
{
    protected function configure()
    {
        $this->setName('colc')
            ->setDescription('Shows output in color')
            ->setHelp('This command shows output in color');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $output->writeln("<info>Today is a windy day</info>");

        $outputStyle = new OutputFormatterStyle('red');
        $output->getFormatter()->setStyle('redt', $outputStyle);

        $output->writeln('<redt>Tomorrow will be snowing</redt>');
    }
}

```

`ColorCommand`以彩色输出文本。

```php
$output->writeln("<info>Today is a windy day</info>");

```

在这种情况下，我们使用内置的`info`格式样式。

```php
$outputStyle = new OutputFormatterStyle('red');
$output->getFormatter()->setStyle('redt', $outputStyle);

$output->writeln('<redt>Tomorrow will be snowing</redt>');

```

我们还可以使用`OutputFormatterStyle`创建自定义输出样式。 我们的`redt`以红色显示文字。

`src/Command/BooksCommand.php`

```php
<?php

namespace App\Command;

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class BooksCommand extends Command
{
    protected function configure() 
    {
        $this->setName('books')
            ->setDescription('Shows books in a table')
            ->setHelp('This command demonstrates the usage of a table helper');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $table = new Table($output);

        $table->setHeaderTitle('Books')
            ->setHeaders(['Title', 'ISBN', 'Author', 'Publisher'])
            ->setRows([
                ['Java Language Features', '978-1-4842-3347-4', 'Kishori Sharan', 'Apress' ],
                ['Python Testing with pytest', '978-1-68-050-240-4', 'Brian Okken', 'The Pragmatic Programmers' ],
                ['Deep Learning with Python', '978-1-61729-443-3', 'Francois Chollet', 'Manning' ],
                ['Laravel up & Running', '978-1-491-93698-5', 'Matt Stauffer', 'O\'Reilly' ],
                ['Sams Teach Yourself TCP/IP', '978-0-672-33789-5', 'Joe Casad', 'SAMS' ]
            ]);

          $table->render();
    }   
}

```

`BooksCommand`使用表格助手以表格格式输出数据。

```php
$table = new Table($output);

```

我们创建一个`Table`帮助器的实例。

```php
$table->setHeaderTitle('Books')
    ->setHeaders(['Title', 'ISBN', 'Author', 'Publisher'])
    ->setRows([
        ['Java Language Features', '978-1-4842-3347-4', 'Kishori Sharan', 'Apress' ],
        ['Python Testing with pytest', '978-1-68-050-240-4', 'Brian Okken', 'The Pragmatic Programmers' ],
        ['Deep Learning with Python', '978-1-61729-443-3', 'Francois Chollet', 'Manning' ],
        ['Laravel up & Running', '978-1-491-93698-5', 'Matt Stauffer', 'O\'Reilly' ],
        ['Sams Teach Yourself TCP/IP', '978-0-672-33789-5', 'Joe Casad', 'SAMS' ]
    ]);

```

我们建立表。 表标题标题由`setHeaderTitle()`指定。 `header`名称由`setHeaders()`指定。 最后，将数据与`setRows()`相加。

```php
$table->render();

```

该表使用`render()`呈现。

`src/Command/AskNameCommand.php`

```php
<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class AskNameCommand extends Command
{
    protected function configure() 
    {
        $this->setName('ask')
            ->setDescription('Interactively asks name from the user')
            ->setHelp('This command asks a user name interactively and prints it');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $helper = $this->getHelper('question');
        $question = new Question("Enter your name: ", "guest");

        $name = $helper->ask($input, $output, $question);
        $message = sprintf("Hello %s!", $name);

        $output->writeln($message);
    }
}

```

`AskNameCommand`使用问题助手来请求用户输入。

```php
$helper = $this->getHelper('question');

```

使用`getHelper()`创建一个问题帮助器。

```php
$question = new Question("Enter your name: ", "guest");

```

创建一个新的`Question`问题。 第二个参数是默认值。

```php
$name = $helper->ask($input, $output, $question);

```

问题通过`ask()`激活。 用户输入存储在`$name`变量中。

```php
$message = sprintf("Hello %s!", $name);

```

我们使用`sprintf()`从用户输入构建消息。

```php
$output->writeln($message);

```

最后，该消息在终端中显示为`writeln()`。

使用`Symfony\Component\Console\Application`创建一个新的 Symfony 应用。

`Application.php`

```php
<?php

require __DIR__ . '/vendor/autoload.php';

use App\Command\TimeCommand;
use App\Command\BooksCommand;
use App\Command\ColorCommand;
use App\Command\AskNameCommand;
use App\Command\MessageCommand;
use Symfony\Component\Console\Application;

$app = new Application();

$app->add(new MessageCommand());
$app->add(new TimeCommand());
$app->add(new AskNameCommand());
$app->add(new BooksCommand());
$app->add(new ColorCommand());

$app->run();

```

我们用五个命令创建一个 Symfony 控制台应用。

```php
$app = new Application();

```

创建一个新的控制台应用。

```php
$app->add(new MessageCommand());
$app->add(new TimeCommand());
$app->add(new AskNameCommand());
$app->add(new BooksCommand());
$app->add(new ColorCommand());

```

我们向应用添加命令。

```php
$app->run();

```

应用从`run()`启动。

```php
$ php application.php list
Console Tool
...
Available commands:
    ask    Interactively asks name from the user
    books  Shows books in a table
    colc   Shows output in color
    help   Displays help for a command
    list   Lists commands
    msg    Prints a user provided message
    time   Shows current date and time

```

我们可以获得命令列表。

```php
$ php application.php books
+----------------------------+--------------- Books -----------------+---------------------------+
| Title                      | ISBN               | Author           | Publisher                 |
+----------------------------+--------------------+------------------+---------------------------+
| Java Language Features     | 978-1-4842-3347-4  | Kishori Sharan   | Apress                    |
| Python Testing with pytest | 978-1-68-050-240-4 | Brian Okken      | The Pragmatic Programmers |
| Deep Learning with Python  | 978-1-61729-443-3  | Francois Chollet | Manning                   |
| Laravel up & Running       | 978-1-491-93698-5  | Matt Stauffer    | O'Reilly                  |
| Sams Teach Yourself TCP/IP | 978-0-672-33789-5  | Joe Casad        | SAMS                      |
+----------------------------+--------------------+------------------+---------------------------+

```

我们运行`books`命令。

```php
$ php application.php time
Current date and time: 2018-12-20T23:27:16+01:00

```

我们运行`time`命令。

在本教程中，我们在 Symfony 控制台应用中创建了五个控制台命令。

```php
$ php application.php ask
Enter your name: Peter
Hello Peter!

```

我们运行`ask`命令。

在本教程中，我们在 Symfony 控制台应用中创建了五个控制台命令。

您可能也对以下相关教程感兴趣： [Symfony 简介](/symfony/intro/)， [Symfony 验证教程](/symfony/validation/)， [Symfony Flash 消息](/symfony/flash/)， [Symfony 服务教程](/symfony/service/) ， [Symfony 表单教程](/symfony/form/)， [PHP 教程](/lang/php/)。