Documentação do Symfony - versão 3.1
Renderizada do repositório symfony-docs-pt-BR no Github
O framework Symfony disponibiliza muitos comandos através do script bin/console
(por exemplo, o comando bem conhecido bin/console cache:clear
). Esses comandos são
criados com o componente Console. Você também pode
usá-lo para criar os seus próprios comandos.
Os comandos são definidos nas classes que devem ser criadas no namespace Command
de seu bundle (por exemplo, AppBundle\Command
) e os seus nomes devem terminar com
sufixo Command
.
Por exemplo, um comando chamado CreateUser
deve seguir essa estrutura:
// src/AppBundle/Command/CreateUserCommand.php
namespace 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)
{
// ...
}
}
Antes de tudo, você deve configurar o nome do comando no método
configure()
. Então você pode, opcionalmente, definir uma mensagem de ajuda
e as opções e argumentos de entrada:
// ...
protected function configure()
{
$this
// the name of the command (the part after "bin/console")
->setName('app:create-users')
// the short description shown while running "php bin/console list"
->setDescription('Creates new users.')
// the full command description shown when running the command with
// the "--help" option
->setHelp("This command allows you to create users...")
;
}
Após configurar o comando, você pode executá-lo no terminal:
1 | $ php bin/console app:create-users
|
Como esperado, esse comando não fará nada pois você não escreveu nenhuma lógica
ainda. Adicione a sua própria lógica dentro do método execute()
, que tem acesso ao
fluxo de entrada (por exemplo, opções e argumentos) e ao fluxo de saída (para escrever
mensagens no console):
// ...
protected function execute(InputInterface $input, OutputInterface $output)
{
// outputs multiple lines to the console (adding "\n" at the end of each line)
$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.');
}
Agora, tente executar o comando:
1 2 3 4 5 6 | $ php bin/console app:create-user
User Creator
============
Whoa!
You are about to create a user.
|
Use opções de entrada ou argumentos para passar informações ao comando:
use Symfony \ Component \ Console \ Input \ InputArgument;
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()
$output->writeln('Username: '.$input->getArgument('username'));
}
Agora, você pode passar o nome de usuário para o comando:
1 2 3 4 5 | $ php bin/console app:create-user Wouter
User Creator
============
Username: Wouter
|
See also
Leia /console/input para obter mais informações sobre as opções e argumentos de console.
Para realmente criar um novo usuário, o comando tem que acessar alguns
serviços. Isso pode ser realizado fazendo o comando
estender a ContainerAwareCommand
// ...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
class CreateUserCommand extends ContainerAwareCommand
{
// ...
protected function execute(InputInterface $input, OutputInterface $output)
{
// ...
// access the container using getContainer()
$userManager = $this->getContainer()->get('app.user_manager');
$userManager->create($input->getArgument('username'));
$output->writeln('User successfully generated!');
}
}
Agora, depois de ter criado os serviços e a lógica necessária, o comando irá executar
o método create()
do serviço app.user_manager
e o usuário
será criado.
Os comandos possuem três métodos de ciclo de vida que são invocados durante a execução do do mesmo:
initialize()
(opcional)interact()
e execute()
. Sua principal finalidade é inicializar variáveis usadas pelos outros
métodos do comando.interact()
(opcional)initialize()
e antes do execute()
.
Sua finalidade é verificar se estão faltando algumas das opções/argumentos
e interativamente pedir ao usuário esses valores. Esse é o último lugar
onde você pode pedir pelas opções/argumentos que estiverem faltando. Após esse
comando, as opções/argumentos que estiverem faltando irão resultar em um erro.execute()
(obrigatório)interact()
e initialize()
.
Ele contém a lógica que você deseja que o comando execute.O Symfony oferece várias ferramentas para ajudar você a testar seus comandos. A mais
útil é CommandTester
. Ela usa as classes de entrada e saída especiais para facilitar o teste sem um
console real:
// tests/AppBundle/Command/CreateUserCommandTest.php
namespace 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
'username' => 'Wouter',
// prefix the key with a double slash when passing options,
// e.g: '--some-option' => 'option_value',
));
// the output of the command in the console
$output = $commandTester->getDisplay();
$this->assertContains('Username: Wouter', $output);
// ...
}
}
Tip
Você também pode testar uma aplicação inteira de console usando
ApplicationTester
.
Note
Ao usar o componente Console em um projeto independente, use
Symfony\Component\Console\Application
e estenda o normal \PHPUnit_Framework_TestCase
.
Para poder utilizar o contêiner de serviço totalmente configurado para seus testes de console
você pode estender o seu teste de
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);
// ...
}
}
O componente Console também contém um conjunto de “helpers” - pequenas ferramentas capazes de ajudá-lo com tarefas diferentes: