命令列


Symfony框架透過bin/console腳本(如,廣為人知的bin/console cache:clear指令)提供了大量指令。這些命令是透過控制台元件#被建立的。你也可以使用它來創建自己的命令。

建立一個指令 

命名透過類別來定義,這些類別必須存放在你的束(如AppBundle\Command)的 Command在命名空間下。類別名稱必須是Command後綴。

例如,一個名為CreateUser的指令必須遵循此結構:

// src/AppBundle/Command/CreateUserCommand.phpnamespace AppBundle\Command; use Symfony\Component\Console\Command\Command;use Symfony\Component\Console\Input\InputInterface;use Symfony\Component\Console\Output\OutputInterface; class CreateUserCommand extends Command{
    protected function configure()
    {
        // ...
    }     protected function execute(InputInterface $input, OutputInterface $output)
    {
        // ...
    }}

設定指令 

##首先,你必須在configure()方法中設定指令的名稱。然後可選擇定義一個幫助資訊(幫助訊息)和輸入選項及輸入參數

(輸入選項與參數):

// ...protected function configure(){
    $this
        // the name of the command (the part after "bin/console")
        // 命令的名字("bin/console" 后面的部分)
        ->setName('app:create-users')         // the short description shown while running "php bin/console list"
        // 运行 "php bin/console list" 时的简短描述
        ->setDescription('Creates new users.')         // the full command description shown when running the command with
        // the "--help" option
        // 运行命令时使用 "--help" 选项时的完整命令描述
        ->setHelp("This command allows you to create users...")
    ;}

#執行指令 

設定指令之後,你就能在終端機(終端機)中執行它:

$  php bin/console app:create-users

你可以已經預期,這個指令將什麼都不做,因為你還沒寫入任何邏輯。在execute()

###方法裡加入你自己的邏輯,這個方法可以存取到輸入流(如,選項和參數)和輸出流寫入訊息到命令列):#########
// ...protected function execute(InputInterface $input, OutputInterface $output){
    // outputs multiple lines to the console (adding "\n" at the end of each line)
    // 输出多行到控制台(在每一行的末尾添加 "\n")
    $output->writeln([
        'User Creator',
        '============',
        '',
    ]);     // outputs a message followed by a "\n"
    $output->writeln('Whoa!');     // outputs a message without adding a "\n" at the end of the line
    $output->write('You are about to ');
    $output->write('create a user.');}
#########現在,嘗試執行此命令:#########
$  php bin/console app:create-user
User Creator============ 
Whoa!You are about to create a user.

控制台輸入 

##使用輸入選項或參數來傳入訊息給指令:

use Symfony\Component\Console\Input\InputArgument; // ...protected function configure(){
    $this
        // configure an argument / 配置一个参数
        ->addArgument('username', InputArgument::REQUIRED, 'The username of the user.')
        // ...
    ;} // ...public function execute(InputInterface $input, OutputInterface $output){
    $output->writeln([
        'User Creator',
        '============',
        '',
    ]);     // retrieve the argument value using getArgument()
    // 使用 getArgument() 取出参数值
    $output->writeln('Username: '.$input->getArgument('username'));

現在,你可以傳入使用者名稱到指令中:

$  php bin/console app:create-user Wouter
User Creator============ 
Username: Wouter

參考#控制台輸出(參數與選項) #以了解更多關於命令列選項和參數的資訊。

#

從服務容器取得服務 

#要真正建立用戶,命令必須要存取某些服務(服務)。這可以透過讓指令繼承ContainerAwareCommand來實現:

// ...use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; class CreateUserCommand extends ContainerAwareCommand{
    // ...     protected function execute(InputInterface $input, OutputInterface $output)
    {
        // ...         // access the container using getContainer()
        // 使用 getContainer() 访问服务容器
        $userManager = $this->getContainer()->get('app.user_manager');
        $userManager->create($input->getArgument('username'));         $output->writeln('User successfully generated!');
    }}

##現在,一旦你創建了所需的服務及其邏輯,命令將執行app.user_manager#服務的##create()方法,然後使用者會被建立的指令生命週期  

指令有三個生命週期方法可以在執行指令時使用:

    initialize()
  • #(可選)
  • ##這個方法在
  • interact()#和execute()方法之前執行。它的主要作用是初始化那些用在命令其餘方法的變數。 interact()
  • (可選)此方法在initialize()
  • 之後、
  • execute() 之前執行。它的作用是檢查是否錯失了某些選項/參數,然後以互動方式向使用者請求這些值。這是你可以問詢錯失的選項/參數的最後一個地方。此後,丟失的選項/參數將導致一個錯誤。 execute()
  • (必須)#此方法在interact()
  • and
  • initialize() 之後執行。它包含你希望命令去執行的邏輯。 測試指令 ¶
Symfony提供了幾個工具來幫你測試指令。最有用的一個是

CommandTester

類別。它使用特殊的input和output類,讓「不在真正控制台中」的測試變得容易:

// tests/AppBundle/Command/CreateUserCommandTest.phpnamespace Tests\AppBundle\Command; use AppBundle\Command\CreateUserCommand;use Symfony\Bundle\FrameworkBundle\Console\Application;use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;use Symfony\Component\Console\Tester\CommandTester; class CreateUserCommandTest extends KernelTestCase{
    public function testExecute()
    {
        self::bootKernel();
        $application = new Application(self::$kernel);         $application->add(new CreateUserCommand());         $command = $application->find('app:create-user');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'  => $command->getName(),             // pass arguments to the helper / 传入参数给helper
            'username' => 'Wouter',             // prefix the key with a double slash when passing options,
            // e.g: '--some-option' => 'option_value',
            // 需要选项时,对key加“双中杠”的前缀,如'--some-option' => 'option_value'
        ));         // the output of the command in the console
        // 控制台中的命令输出
        $output = $commandTester->getDisplay();
        $this->assertContains('Username: Wouter', $output);         // ...
    }}


使用

ApplicationTester
你也可以測試整個控制台程式。


當Console元件被單獨使用時,使用
Symfony\Component\Console\Application
和常規的

\PHPUnit_Framework_TestCase#

要在你的console tests中使用最完整的服務容器設置,你可以從KernelTestCase 中繼承你的測試:

// ...use Symfony\Component\Console\Tester\CommandTester;use Symfony\Bundle\FrameworkBundle\Console\Application;use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; class CreateUserCommandTest extends KernelTestCase{
    public function testExecute()
    {
        $kernel = $this->createKernel();
        $kernel->boot();         $application = new Application($kernel);
        $application->add(new CreateUserCommand());         $command = $application->find('app:create-user');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'  => $command->getName(),
            'username' => 'Wouter',
        ));         $output = $commandTester->getDisplay();
        $this->assertContains('Username: Wouter', $output);         // ...
    }}

控制台助手

Console元件還包括了一組「助手」(helpers)-不同的小工具可以幫助你完成不同的任務:

  • Question Helper(提問助手): interactively ask the user for information
  • Formatter Helper(格式助手): customize the output colorization
  • Progress Bar(進度列): shows a progress bar
  • Table(表格): displays tabular data as a table